redis
redis简介
redis是一个用c语言编写的,开源的,基于内存运行并支持持久化,高性能的nosql数据库,也是当前热门的NOSQL数据库之一,redis中的数据大部分时间都是存储在内存中的,适合存储平凡访问,数据量比较小的数据。
redis服务
启动
- 方式一:redis压缩包解压目录下双击文件redis-server
- 方式二:redis压缩包解压目录下进入cmd窗口,输入redis-server
- 指定配置文件启动 redis-server redis.windows.conf
关闭
在另外一个cmd窗口输入:redis-cli-shutdown
redis的客户端
redis的客户端用来连接redis服务,向redis服务端发送命令,并且显示redis服务处理结果。
启动redis客户端
redis-cli:是redis自带客户端,使用命令redis-cli就可以启动redis的客户端程序。
redis-cli:默认连接127.0.0.1(本机)的6379端口上的redis服务。
redis-cli -p 端口号:连接127.0.0.1(本机)的指定端口上的redis服务。
redis-cli -h ip地址 -p 端口:连接指定ip主机上的指定端口的redis服务。
关闭redis客户端
在客户端执行命令:exit或者quit
redis基本知识
-
测试redis服务的性能:
redis-benchmark
-
查看redis服务是否正常运行:
ping 如果正常----pong
E:\redis\redis>redis-cli 127.0.0.1:6379> ping PONG
-
查看redis服务器的统计信息:
info 查看redis服务的所有统计信息
info [信息段] 查看redis服务器指定的统计信息,如:info replication
127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_replid:bcd13e1c342c74a35b608eef42be24948ee27665 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
redis的数据库实例
redis数据库实例作用类似于mysql的数据库实例,redis中的数据库实例只能由redis服务创建和维护,开发人员不能修改和自行创建数据库实例:默认情况下,redis会自动创建16个数据库实例,并且给这些数据库实例进行编号,从0开始,一直到15,使用时通过编号来使用数据库;可以通过配置文件来指定redis自动创建的数据库个数。
默认情况下,redis客户端连接的是编号是0号的数据库实例。可以使用select index切换数据库实例。
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> select 0
OK
查看当前数据库实例中所有key的数量:dbsize
127.0.0.1:6379> dbsize
(integer) 3
查看当前数据库实例中所有的key:keys *
127.0.0.1:6379> keys *
1) "key:__rand_int__"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
清空数据库实例:flushdb
127.0.0.1:6379> keys *
1) "key:__rand_int__"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty list or set)
查看redis中的配置信息:config get *
查看指定配置信息:config get port
127.0.0.1:6379> config get port
1) "port"
2) "6379"
redis的五种数据结构
- string 单key:单value:username:zhangsan age:20
- list 单key:多有序value:contacts:xxxx,xxxx,xxxx
- set 单key:多无序value:city:bj sh sq tj (这里的数据是没有索引的,并且数据不能重复)
- hash 单key:对象(属性:值):student:id:1001,name:zhangsan,age:20
- zset 单key:多value:city:100 tj,1200 cq,1500 sh(元素不能重复)
redis的常用操作命令
redis的key的操作命令
- 查看数据库中的key:keys pattern
—>*:匹配0个或者多个字符
—>?:匹配一个字符
—>[]:匹配[]里边的一个字符
-
keys *;查看数据库中所有key
-
keys k*;查看数据库中所有以k开头的key
-
keys h*o:查看数据库中所有以h开头,以o结尾的,并且中间只有一个字符的key
-
keys h[abc]llo:查看数据库中所有以h开头,以llo结尾的,并且 h后边只能取abc中的一个字符的key。
- 判断key在数据库中是否存在
-
exists key 如果存在,则返回1,如果不存在,则返回0
127.0.0.1:6379> exists k1 (integer) 1
-
exists key [key key key] 返回值是存在的key的数量
//在这里k1,k2存在,k3不存在
127.0.0.1:6379> exists k1 k3 k2
(integer) 2
- 移动指定key到指定的数据库实例
- 指令:move key index
127.0.0.1:6379> move k1 2
(integer) 1
- 查看指定的key的剩余生存时间
-
指令:ttl key
—>key不存在:返回-2
—>key没有设置生存时间:返回-1
127.0.0.1:6379> ttl k1 (integer) -1
-
设置key的最大生存时间
指令:expire key seconds
explire k2 20(单位秒)
127.0.0.1:6379> ttl k1
(integer) -1
127.0.0.1:6379> expire k1 30
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 25
127.0.0.1:6379> ttl k1
(integer) 14
127.0.0.1:6379> ttl k1
(integer) -2
- 查看指定key的数据类型
-
指令:type key
127.0.0.1:6379> type k2 string
- 重命名key
-
指令:rename key newname
127.0.0.1:6379> rename k1 k OK
- 删除key
-
指令:del key [key key …]
—>:返回值是实际删除的key数量
127.0.0.1:6379> keys * 1) "hello" 2) "k" 3) "k2" 127.0.0.1:6379> del k (integer) 1 127.0.0.1:6379> keys * 1) "hello" 2) "k2"
redis中有关string类型数据的操作命令
-
将string类型数据设置到redis中
指令:set 键 值
127.0.0.1:6379> set name zhangsan OK
如果key已经存在,会把之前的value覆盖
-
从redis中获取string类型的数据
指令:get 键
127.0.0.1:6379> get name "zhangsan"
-
追加字符串
指令:append key value
---->:返回追加之后的字符串长度
如果key不存在,则新创建一个key,并且把value值设置为value
127.0.0.1:6379> append name lisi (integer) 12 127.0.0.1:6379> get name "zhangsanlisi"
-
获取字符串数据的长度
指令:strlen key
127.0.0.1:6379> strlen name (integer) 12
-
将字符串数值进行加1运算
指令:incr key
—>:返回加1之后的数据
如果key不存在,首先设置一个key,值初始化为0,然后进行incr运算。
key必须是数值,否则报错。
127.0.0.1:6379> incr age (integer) 1 127.0.0.1:6379> incr age (integer) 2
-
将字符串数值进行减1运算
指令:decr key
—>:返回减1之后的数据
如果key不存在,首先设置一个key,值初始化为0,然后进行decr运算。
key必须是数值,否则报错。
127.0.0.1:6379> get age "2" 127.0.0.1:6379> decr age (integer) 1
-
将字符串数值进行加offset运算
指令:incrby key offset
—>:返回加offset运算后的数据
如果key不存在,首先设置一个key,值初始化为0,然后进行incrby运算。
key必须是数值,否则报错。
127.0.0.1:6379> incrby age 20 (integer) 21
-
将字符串数值进行减offset运算
指令:decrby key offset
—>:返回减offset运算后的数据
如果key不存在,首先设置一个key,值初始化为0,然后进行decrby运算。
key必须是数值,否则报错。
127.0.0.1:6379> decrby age 5 (integer) 16
-
闭区间获取字符串key中从startIndex到endIndex的字符组成的子字符串
指令:getrange key startIndex endIndex
—>:下标自左到右,从0开始,最后一个字符的下标是字符串长度-1;
—>:字符串中每一个下标也可以是负数,负下标表示自左至右,从-1开始,依次往前,最右边一个字符的下标是-1
127.0.0.1:6379> getrange name 3 5 "ngs" 127.0.0.1:6379> getrange name -4 -1 "lisi"
-
用value覆盖从下标为startIndex开始的字符串
指令:setrange key startIndex value
—>:返回的是修改后的字符串长度
—>:修改的长度为输入的字符串的长度
127.0.0.1:6379> setrange name 7 wangwu (integer) 13 127.0.0.1:6379> get name "zhangsawangwu" 127.0.0.1:6379> setrange name 5 123 (integer) 13 127.0.0.1:6379> get name "zhang123angwu"
-
设置字符串数据的同时,设置它最大生命周期
指令:setex key seconds value
127.0.0.1:6379> setex x 10 vx OK 127.0.0.1:6379> ttl x (integer) 8 127.0.0.1:6379> ttl x (integer) 5 127.0.0.1:6379> ttl x (integer) -2
-
设置string类型数据到redis数据库中,如果key不存在则设置成功,否则放弃设置
指令:setnx key value
127.0.0.1:6379> setnx name zhaoqian (integer) 0 127.0.0.1:6379> get name "zhang123angwu"
-
批量设置string类型数据到redis数据库中,当所有key都不存在则设置成功,只要有一个key已经存在就放弃设置
指令:msetnx 键1 键2 键3…
127.0.0.1:6379> msetnx k14 v14 k15 v15 (integer) 1
-
批量将string类型的数据设置到redis中
指令:mset 键1 键2 键3…
127.0.0.1:6379> mset k10 v10 k11 v11 k12 v13 OK
-
批量从redis中获取string类型的数据
指令:mget 键1 键2 键3…
127.0.0.1:6379> mget k11 k12 k13 1) "v11" 2) "v12" 3) "v13"
redis中有关list类型数据的操作指令
-
将一个或者多个值插入到列表的表头(左侧)
指令:lpush key [value value …]
127.0.0.1:6379> lpush list1 1 2 3 (integer) 3
-
获取指定列表中指定下标区间的元素
指令:lrange key startIndex endIndex
127.0.0.1:6379> lrange list1 0 2 1) "3" 2) "2" 3) "1" //取出全部结果 127.0.0.1:6379> lrange list1 0 -1 1) "3" 2) "2" 3) "1"
-
将一个或者多个值依次插入到列表的表尾(右侧)
指令:rpush key [value value …]
127.0.0.1:6379> rpush lost2 1 2 3 4 5 6 (integer) 6 127.0.0.1:6379> lrange lost2 0 -1 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6"
-
从指定列表中移除并且返回表头元素
指令:lpop key
127.0.0.1:6379> lpop lost2 "1" 127.0.0.1:6379> lrange lost2 0 -1 1) "2" 2) "3" 3) "4" 4) "5" 5) "6"
-
从指定列表中移除并返回表尾元素
指令:rpop key
127.0.0.1:6379> rpop list1 "1"
-
获取指定列表中指定下标的元素
指令:lindex key index
127.0.0.1:6379> lindex lost2 1 "3"
-
获取指定列表的长度
指令:llen key
127.0.0.1:6379> llen lost2 (integer) 5
-
根据count的值移除列表中跟value相等的数据
指令:lrem key count value
—>count>0:从列表的左侧移除|count|个跟value相等的数据
—>count<0:从列表的右侧移除|count|个跟value相等的数据
—>count=0:从列表中移除所有跟value相等的数据
127.0.0.1:6379> lpush list3 1 1 2 3 3 4 5 1 1 5 2 2 3 2 3 (integer) 15 127.0.0.1:6379> lrange list3 0 -1 1) "3" 2) "2" 3) "3" 4) "2" 5) "2" 6) "5" 7) "1" 8) "1" 9) "5" 10) "4" 11) "3" 12) "3" 13) "2" 14) "1" 15) "1" 127.0.0.1:6379> lrem list3 1 2 (integer) 1 127.0.0.1:6379> lrange list3 0 -1 1) "3" 2) "3" 3) "2" 4) "2" 5) "5" 6) "1" 7) "1" 8) "5" 9) "4" 10) "3" 11) "3" 12) "2" 13) "1" 14) "1" 127.0.0.1:6379> lrem list3 0 1 (integer) 4 127.0.0.1:6379> lrange list3 0 -1 1) "3" 2) "3" 3) "2" 4) "2" 5) "5" 6) "5" 7) "4" 8) "3" 9) "3" 10) "2"
redis中有关set类型数据的操作指令
-
将一个或者多个元素添加到指定集合中
指令:sadd key value
—>返回放入成功的元素个数
如果元素已经存在,则会忽略放入
127.0.0.1:6379> sadd set01 1 2 3 1 (integer) 3 127.0.0.1:6379> smembers set01 1) "1" 2) "2" 3) "3" 127.0.0.1:6379> sadd set01 4 5 6 (integer) 3 127.0.0.1:6379> smembers set01 1) "1" 2) "2" 3) "3" 4) "4" 5) "5" 6) "6"
-
获取指定集合中所有的元素
指令:smembers key
127.0.0.1:6379> smembers set01 1) "1" 2) "2" 3) "3"
-
判断指定元素在集合中是否存在
指令:sismember key member
—>存在返回1,不存在返回0
127.0.0.1:6379> sismember set01 3 (integer) 1 127.0.0.1:6379> sismember set01 7 (integer) 0
-
获取指定集合的长度
指令:scard key
127.0.0.1:6379> scard set01 (integer) 6
-
移除指定集合中一个或者多个元素
指令:srem key member…
—>:不存在元素会被忽略
—>:返回成功移除的元素个数
127.0.0.1:6379> srem set01 1 2 3 (integer) 3 127.0.0.1:6379> smembers set01 1) "4" 2) "5" 3) "6"
-
随机获取指定集合中的一个元素
指令:srandmember key [count]
—>:count>0;随机获取的多个元素之间不能重复
—>:count<0;随机获取的多个元素之间可能重复
127.0.0.1:6379> sadd set02 a b c d e f g (integer) 7 127.0.0.1:6379> srandmember set02 "d" 127.0.0.1:6379> srandmember set02 "c" 127.0.0.1:6379> srandmember set02 3 1) "g" 2) "e" 3) "f" 127.0.0.1:6379> srandmember set02 -3 1) "d" 2) "g" 3) "g" 127.0.0.1:6379> srandmember set02 -3 1) "f" 2) "b" 3) "e"
-
从指定集合中随机移除一个或多个元素
指令:spop key [count]
127.0.0.1:6379> spop set02 "d" 127.0.0.1:6379> spop set02 2 1) "a" 2) "e" 127.0.0.1:6379> smembers set02 1) "g" 2) "c" 3) "f" 4) "b"
-
将指定集合中的元素移动到另一个集合
指令:smove source dest member
127.0.0.1:6379> smove set01 set02 4 (integer) 1 127.0.0.1:6379> smembers set02 1) "g" 2) "c" 3) "f" 4) "b" 5) "4"
-
获取第一个集合中有但是其他集合中都没有的元素组成的新集合
指令:sdiff key key key …
127.0.0.1:6379> smembers set01 1) "5" 2) "6" 127.0.0.1:6379> smembers set02 1) "g" 2) "c" 3) "f" 4) "b" 5) "4" 127.0.0.1:6379> smembers set03 1) "a" 2) "c" 3) "e" 4) "b" 5) "d" 127.0.0.1:6379> sdiff set02 set01 set03 1) "g" 2) "f" 3) "4"
-
获取所有指定集合中都有的元素组成的新集合
-
指令:sinter key key key …
127.0.0.1:6379> sinter set02 set03 1) "c" 2) "b"
-
获取所有指定集合中所有元素组成的大集合
指令:sunion key key key…
127.0.0.1:6379> sunion set01 set02 set03 1) "b" 2) "4" 3) "e" 4) "a" 5) "f" 6) "d" 7) "c" 8) "g" 9) "6" 10) "5"
redis中有关hash类型数据的操作命令
-
将一个或者多个field-value对设置到哈希表中(如果key已经存在会把value以前的值覆盖掉)
指令:hset key filed1 value1 [filed2 value2 …]
或者:hmset key filed1 value1 [filed2 value2 …]
127.0.0.1:6379> hset student1 name zhangsan age 1 xingbie nan (integer) 3 127.0.0.1:6379> hset student1 no 123456 (integer) 1
-
获取指定哈希表中指定field的值
指令:hget key field
127.0.0.1:6379> hget student1 name "zhangsan"
-
批量获取指定哈希表中的field的值
指令:hmget key1 field1 [key2 field2 …]
127.0.0.1:6379> hmget student1 name no 1) "zhangsan" 2) "123456"
-
获取指定哈希表中所有的filed和value
指令:hgetall key
127.0.0.1:6379> hgetall student1 1) "name" 2) "zhangsan" 3) "age" 4) "1" 5) "xingbie" 6) "nan" 7) "no" 8) "123456"
-
从指定哈希表中删除一个或者多个field
指令:hdel key field [field1 field2 field3 …]
127.0.0.1:6379> hdel student1 name age (integer) 2 127.0.0.1:6379> hgetall student1 1) "xingbie" 2) "nan" 3) "no" 4) "123456"
-
获取指定哈希表中所有的filed个数
指令:hlen key
127.0.0.1:6379> hlen student1 (integer) 2
-
判断指定哈希表中是否存在某一个field
指令:hexists key field
—>:存在返回1,不存在返回0
127.0.0.1:6379> hexists student1 name (integer) 0 127.0.0.1:6379> hexists student1 no (integer) 1
-
获取指定哈希表中所有的field列表
指令:hkeys key
127.0.0.1:6379> hkeys student1 1) "xingbie" 2) "no"
-
获取指定哈希表中所有的value列表
指令:hvals key
127.0.0.1:6379> hvals student1 1) "nan" 2) "123456"
-
对指定哈希表中指定的field值进行整数加法和浮点数加法运算运算
指令:hincrby key field int (整数加法)
指令:hincrbyfloat key field int(浮点数加法)
127.0.0.1:6379> hincrby student1 no 1 (integer) 123457 127.0.0.1:6379> hset student1 score 80 (integer) 1 127.0.0.1:6379> hincrbyfloat student1 score 5.5 "85.5"
-
将一个field和value对设置到哈希表中(当key-field存在时,放弃设置)
指令:hsetnx key field value
127.0.0.1:6379> hsetnx student1 no 123 (integer) 0 127.0.0.1:6379> hget student1 no "123457"
redis中有关zset类型数据的操作指令
zset类型数据是有序集合,每一个元素都关联一个分数,redis会根据分数对元素类型进行排序,分数可以重复
-
将一个或者多个member及其score值加入有序集合(如果元素已经存在,则把分数覆盖)
指令:zadd key score member [score member …]
127.0.0.1:6379> zadd zset1 20 z1 30 z2 50 z3 40 z4 (integer) 4
-
获取有序集合中指定下标区间的元素
指令:zrange key startIndex endIndex
127.0.0.1:6379> zrange zset1 0 -1 1) "z1" 2) "z2" 3) "z4" 4) "z3"
-
获取指定有序集合中指定分数区间的元素(闭区间)
指令:zrangebyscore key min max [withscores]
127.0.0.1:6379> zrangebyscore zset1 30 50 1) "z2" 2) "z4" 3) "z3"
-
删除指定有序集合中一个或者多个元素
指令:zrem key member [member …]
127.0.0.1:6379> zrem zset1 z3 z4 (integer) 2 127.0.0.1:6379> zrange zset1 0 -1 1) "z1" 2) "z2"
-
获取指定有序集合中所有元素的个数
指令:zcard key
127.0.0.1:6379> zcard zset1 (integer) 2
-
获取指定有序集合中指定元素的排名(排名从0开始,从小到大的排名)
指令:zrank key member
127.0.0.1:6379> zadd zset1 30 z3 50 z4 60 z5 (integer) 3 127.0.0.1:6379> zrange zset1 0 -1 1) "z1" 2) "z2" 3) "z3" 4) "z4" 5) "z5" 127.0.0.1:6379> zrank zset1 z4 (integer) 3
-
获取指定有序集合中分数在指定区间内的元素的个数(闭区间)
指令:zcount key min max
127.0.0.1:6379> zcount zset1 30 40 (integer) 2
-
获取指定有序集合中指定元素的分数
指令:zcore key member
127.0.0.1:6379> zscore zset1 z4 "50"
-
获取指定有序集合中指定元素的排名(,从0开始,从大到小的排名)
指令:zrevrank key member
127.0.0.1:6379> zrevrank zset1 z4 (integer) 1
redis配置文件
在redis根目录下提供的redis.conf配置文件:
可以配置一些redis服务端运行时的参数,如果不使用配置文件,那么redis会按照默认的参数运行,如果使用配置文件,在启动redis服务时必须指定所使用的配置文件。
redis中配置文件中关于网络的配置
port:指定redis服务所使用的端口,默认使用6379.
bind:配置客户端连接redis服务时,所能使用的ip地址,默认可以使用redis服务所在的主机上任何一个ip都可以;一般情况下,都会配置一个ip,而且通常是一个真实的。
如果配置了port和bind,则客户端连接redis服务时,必须指定端口和ip
redis -cli -h 192.168.11.128 -p 6380
redis -cli -h 192.168.11.128 -p 6380 shutdown
redis中常规配置
loglevel:配置日志级别,开发阶段配置debug,上线阶段配置notice或者warning。
logfile:指定日志文件,redis在运行过程中,会输出一些日志信息:默认情况下,这些日志信息会输出到控制台,我们可以使用logfile配置日志文件。
databases:配置redis服务默认创建的数据库实例个数,默认为16个。
redis中安全配置
requirepass:设置访问redis服务时所使用的密码,默认不使用。这个参数必须在protected-mode=yes时才使用。
一旦设置了密码验证,客户端连接redis
不推荐使用,因为这会在每次请求时验证密码,影响redis的高效性。
redis持久化
redis提供持久化策略,在适当时机采用适当字段把内存中的数据持久化到磁盘中,每次redis服务启动时都可以把磁盘上的数据再次加载内存中使用。
RBD策略
该策略在指定时间间隔内,redis服务执行指定次数的读写操作,会自动触发一次持久化操作。
//默认使用下面三种策略
# 900 秒(15 分钟)后,如果至少 1 个键发生了变化
# 300 秒(5 分钟)后,如果至少有 10 个键被更改
# 如果至少有 10000 个键被更改,则在 60 秒后执行
save 900 1
save 300 10
save 60 10000
save :配置持久化策略
dbfilename:配置redis RDB持久化数据存储文件
dir:配置redis RDB 持久化文件所在目录
AOF策略
该策略采用操作日志来记录进行的每一次写操作,每次redis服务启动时,都会重新执行一遍操作日志中的指令。
效率低下,redis默认不开启AOF
appendonly:配置是否开启AOF策略
appendfilename:配置操作日志文件
根据数据的特点决定开启那种持久化策略:
一般情况下,开启RDB足够了。
redis的事务
事务:把一组数据库命令放在一起执行,保证操作的原子性,要么同时成功,要么同时失败。
redis的事务:允许把一组redis命令放在一起执行,把命令进行序列化,然后一起执行,保证部分原子性。
- multi:用来标记一个事务的开始
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
- exec:用来执行事务队列中的命令
127.0.0.1:6379> exec
1) OK
2) OK
- redis的事务只能保证部分原子性
如果一组命令中,有的压入事务队列过程中发生错误的命令,则本事务中所有的命令都不执行,能够保证事务的原子性。
如果一组命令在压入队列过程中正常,但是在执行事务队列命令时发生了错误,则只会影响发生错误的指令,不会影响其他命令的执行,不能够保证事务的原子性。
- discard:清除所有已经压入队列中的命令,并且结束整个事务。
- watch:监听某一个key,当事务在执行过程中,此键代码的值发生变化,则本事务放弃执行,否则,正常执行。
- unwatch:放弃监控所有的键
redis消息的发布和订阅
redis客户端订阅频道,消息的发布者往频道上发布消息,所有订阅此频道的客户端都能够接受到消息
-
subscribe:订阅一个或者多个频道
subscrible ch1 ch2 ch3 …
-
pupbish:将消息发布到指定频道
publish ch1 hello
redis的主从复制
主少从多,主写从读,读写分离,主写同步复制到从。
搭建一主二从redis集群(这里是在windows上模拟)
搭建三台redis服务
复制三分配置文件:redis.6379.conf redis.6380.conf redis.6381.conf
修改配置文件 (以6379.conf为例)
- port:6379
- dbfilename dump6379.conf
分别使用三个redis配置文件启动三个redis服务
redis-server redis.6379.conf
redis-server redis.6380.conf
redis-server redis.6381.conf
通过redis客户端分别连接三台redis服务
redis-cli -h 127.0.0.1 -p 6379
redis-cli -h 127.0.0.1 -p 6380
redis-cli -h 127.0.0.1 -p 6381
查看三台redis服务在集群中的主从角色:(其他两台一样)
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0//从机个数
master_replid:358f48caa809109333222f123f9b37afbda850cc
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
默认情况下,所有的redis服务都是主机,即都能写和读,但是都还没有从机。
三台redis服务互相独立,互不影响。
设置主从关系(设从不设主)
(6381和6380相同,不演示)
在6380上执行:slaveof 127.0.0.1 6379
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up//连接状态
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ced9fd56bbd60eb43c67cf163a294e8096e5cc00
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
6379主机的从机加一
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=56,lag=0
master_replid:ced9fd56bbd60eb43c67cf163a294e8096e5cc00
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:56
全量复制:一旦主从关系确定,会自动把主机上已有的数据同步复制到从库
增量复制:主库写数据会自动同步到从库
往6379添加数据
127.0.0.1:6379> set k1 v1
OK
9380上也会添加数据
127.0.0.1:6380> keys *
1) "k1"
在9380和6381上执行—> set k3 v3会报错,主机可以写和读,从机只能读,不能写
-
主机宕机,从机原地待命(从机依旧可以读数据)
-
主机恢复,一切恢复正常。
-
从机宕机,主机少一个从机,其他从机不变
-
从机恢复,需要重新设置主从关系
-
从机上位(主机宕机,长时间修不好)
-
主机断开
127.0.0.1:6379> shutdown
-
从机断开原来主从关系
127.0.0.1:6380> slaveof no one OK 127.0.0.1:6380> info replication # Replication role:master connected_slaves:0 master_replid:f68e874539c7ea10def5440bbf3c937b7613a545 master_replid2:ced9fd56bbd60eb43c67cf163a294e8096e5cc00 master_repl_offset:1970 second_repl_offset:1971 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:1970
-
重新设置主从关系
在6381上执行:slaveof 127.0.0.1 6380
127.0.0.1:6381> slaveof 127.0.0.1 6380 OK 127.0.0.1:6381> info replication # Replication role:slave master_host:127.0.0.1 master_port:6380 master_link_status:up master_last_io_seconds_ago:4 master_sync_in_progress:0 slave_repl_offset:1984 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:f68e874539c7ea10def5440bbf3c937b7613a545 master_replid2:ced9fd56bbd60eb43c67cf163a294e8096e5cc00 master_repl_offset:1984 second_repl_offset:1971 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:141 repl_backlog_histlen:1844
-
-
之前的主机恢复(变成孤家寡人)
-
重启6379服务:
-
E:\redis\redis>redis-server redis.6379.conf
-
客户端连接6379:
not connected> redis-cli -h 127.0.0.1 -p 6379
-
在6379上执行:slave 127.0.0.1 6381(让9379变为从机的从机)
127.0.0.1:6379> slaveof 127.0.0.1 6381 OK
小结:一台主机可以配置多台从机,一台从机又可以配置多台从机,从而形成一个庞大的集群结构,减轻一台服务器的压力,但是增加了服务器间的延迟时间。
-
redis的哨兵模式
主机宕机,从机自动上位。
-
搭建一主二从集群架构
-
提供哨兵配置文件:
在redis安装目录下创建配置文件:redis_sentinel.conf
往里面写入:sentinel monitor dc-redis 127.0.0.1 6379 1
-
新开一个窗口,启动哨兵服务:
redis-sentinel redis_sentinel.conf
-
主机宕机:
关闭主机6379后,哨兵程序会自动选择从机上位。
-
之前主机恢复,会自动从属于新的主机
jedis操作redis
import redis.clients.jedis.Jedis;
import java.util.Set;
public class JedisKeyTest {
public static void main(String[] args){
//连接redis
Jedis jedis=new Jedis("127.0.0.1" ,6379);
//使用jedis对象操作redis服务
String ret=jedis.ping();
System.out.println(ret);
Set<String> keys= jedis.keys("*");
for (String key:keys){
System.out.println(key);
}
System.out.println("----------------------");
jedis.set("k3","v3");
Set<String> keys1= jedis.keys("*");
for (String key:keys1){
System.out.println(key);
}
}
}
PONG
k1
k2
----------------------
k3
k1
k2
redis工具类
在resources新建:redis.properties
文件里面写入
redis.host=127.0.0.1
redis.port=6379
#最大连接数
redis.maxTotal=30
redis.maxIdle=10
新建JedisUtil类
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ResourceBundle;
public class JedisUtil {
private static JedisPool jedisPool=null;
private static String host=null;
private static int port;
private static int maxTotal;
private static int maxIdle;
static {
ResourceBundle resourceBundle=ResourceBundle.getBundle("redis");
host=resourceBundle.getString("redis.host");
port= Integer.parseInt(resourceBundle.getString("redis.port"));
maxTotal= Integer.parseInt(resourceBundle.getString("redis.maxTotal"));
maxIdle= Integer.parseInt(resourceBundle.getString("redis.maxIdle"));
JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPool=new JedisPool(jedisPoolConfig,host,port);
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
使用工具类
Jedis jedis=JedisUtil.getJedis();