redis总结

一、什么是redis数据库?

        redis数据库是一种非关系型数据库,全称(Remote Dctionary Server)远程字典服务。是基于内存的,支持持久化,支持网络的高速缓存数据库。
        redis数据库是以键值对方式存储,key值为字符串,value值类型包含字符串(String),哈希(Hash),列表(List),集合(Set),有序集合(Zset)五种基本数据类型,地理位置(Geo),基数统计(Hyperloglog),位图(Bitmap)三种特殊数据类型。

二、redis入门命令

下面实验环境基于windows版本redis。

1.基础命令

启动redis服务端

E:\redis>redis-server.exe redis.windows.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 76804
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[76804] 14 Jan 10:58:12.918 # Server started, Redis version 3.2.100
[76804] 14 Jan 10:58:12.922 * DB loaded from disk: 0.001 seconds
[76804] 14 Jan 10:58:12.922 * The server is now ready to accept connections on port 6379

使用客户端进行一些基本操作

E:\redis>redis-cli.exe -h 127.0.0.1 -p 6379 -a yinkeqi /* 使用客户端连接redis服务端,-h指定ip,-p指定端口,-a指定密码 */
127.0.0.1:6379> ping    								/* ping检查连接是否正常 */
PONG
127.0.0.1:6379> select 1  								/* 切换redis库,默认为0号库,切换为1号库 */
OK
127.0.0.1:6379[1]> dbsize 								/* 查看当前库的大小 */
(integer) 0
127.0.0.1:6379[1]> set a 1  							/* 设置一个键值 */
OK
127.0.0.1:6379[1]> dbsize  								/* 查询当前库的大小 */
(integer) 1
127.0.0.1:6379[1]> flushdb								/* 清空当前库 */
OK
127.0.0.1:6379[1]> dbsize								
(integer) 0
127.0.0.1:6379[1]> flushall								/*	清空所有库 */
OK
127.0.0.1:6379[1]> shutdown								/*	客户端关闭redis服务 */
not connected>
2.键命令
127.0.0.1:6379[1]> set language english    				/* 设置键值 */
OK
127.0.0.1:6379[1]> get language							/* 获取键值 */
"english"
127.0.0.1:6379[1]> del language							/* 删除键值 */
(integer) 1
127.0.0.1:6379[1]> set language english
OK
127.0.0.1:6379[1]> set user yinkeqi
OK
127.0.0.1:6379[1]> keys *u*								/* 查询符合正则key */
1) "user"
2) "language"
127.0.0.1:6379[1]> exists user							/* 判断key是否存在 */
(integer) 1
127.0.0.1:6379[1]> ttl user								/* 获取key的失效时间,不会失效返回-1,已经失效返回0,返回正数表示还有多少秒失效 */
(integer) -1
127.0.0.1:6379[1]> expire user 10						/* 设置key的失效时间 */
(integer) 1
127.0.0.1:6379[1]> ttl user
(integer) 5
127.0.0.1:6379[1]> ttl user
(integer) 0
127.0.0.1:6379[1]> rename user username					
(error) ERR no such key
127.0.0.1:6379[1]> set user yinkeqi
OK
127.0.0.1:6379[1]> rename user username					/* 修改key值名称 */
OK
127.0.0.1:6379[1]> keys user
(empty list or set)
127.0.0.1:6379[1]> keys user*
1) "username"

三、redis五大基本类型

1.String类型

String类型是最常用的redis数据结构,类似java的字符串和数值类型。包含对字符串的设置、获取、拼接、长度获取、截取、批量设置、批量获取。数值类型的自增、自减、加、减。还有setnx(不存在时设置,存在不设置)、setex(设置字符串同时设置失效时间)。

127.0.0.1:6379[1]> set user yinkeqi						/* 设置字符串类型的值 */
OK
127.0.0.1:6379[1]> get user								/* 获取字符串类型的值 */
"yinkeqi"
127.0.0.1:6379[1]> append user yyds						/* 拼接字符串 */
(integer) 11
127.0.0.1:6379[1]> get user
"yinkeqiyyds"
127.0.0.1:6379[1]> strlen user							/* 获取字符串长度 */
(integer) 11
127.0.0.1:6379[1]> substr user 1 3						/* 截取字符串,返回截取后的字符串,原redis存储的字符串不变 */
"ink"
127.0.0.1:6379[1]> substr user 3 6
"keqi"
127.0.0.1:6379[1]> incr user
(error) ERR value is not an integer or out of range
127.0.0.1:6379[1]> set age 18
OK
127.0.0.1:6379[1]> incr age								/* 数值类型自增 */		
(integer) 19
127.0.0.1:6379[1]> decr age								/* 数值类型自减 */
(integer) 18
127.0.0.1:6379[1]> incrby age 8							/* 数值类型加值 */
(integer) 26
127.0.0.1:6379[1]> decrby age 6							/* 数值类型减值 */
(integer) 20
127.0.0.1:6379[1]> mset name yinkeqi age 18 sex y		/* 批量设置字符串 */
OK
127.0.0.1:6379[1]> mget name age sex					/* 批量获取字符串 */
1) "yinkeqi"
2) "18"
3) "y"
127.0.0.1:6379[1]> setnx name zhangsan					/* 如果不存在就设置字符串,返回1;如果存在就不设置字符串,返回0 */
(integer) 0
127.0.0.1:6379[1]> setnx money 10000
(integer) 1
127.0.0.1:6379[1]> setex girlfriend 10 lisi				/* 设置字符串并设置失效时间 */
OK
127.0.0.1:6379[1]> ttl girlfriend
(integer) 2
127.0.0.1:6379[1]> ttl girlfriend
(integer) -2
127.0.0.1:6379[1]> get girlfriend
(nil)
2.Hash类型

Hash类型类似java的map数据结构,以键值对方式存在。命令主要以h开头,包括对键值对的设置、删除、获取、批量设置、长度获取、是否存在、获取所有键值对、获取所有key、获取所有value。

127.0.0.1:6379[1]> hset family sister lisi              /* 设置hash类型的值 */
(integer) 1
127.0.0.1:6379[1]> hget family sister					/* 获取hash类型的值 */ 
"lisi"
127.0.0.1:6379[1]> hmset family brother zhangsan father wangwu mother zhaoliu	/* 批量设置hash类型的值 */
OK															
127.0.0.1:6379[1]> hmget family father mother brother sister					/* 批量获取hash类型的值 */ 
1) "wangwu"
2) "zhaoliu"
3) "zhangsan"
4) "lisi"
127.0.0.1:6379[1]> hgetall family						/* 获取hash类型的所有值 */
1) "brother"
2) "zhangsan"
3) "sister"
4) "lisi"
5) "father"
6) "wangwu"
7) "mother"
8) "zhaoliu"
127.0.0.1:6379[1]> hdel family sister					/* 删除hash类型的值 */
(integer) 1
127.0.0.1:6379[1]> hgetall family
1) "brother"
2) "zhangsan"
3) "father"
4) "wangwu"
5) "mother"
6) "zhaoliu"
127.0.0.1:6379[1]> hlen family							/* 获取hash类型的大小 */
(integer) 3
127.0.0.1:6379[1]> hexists family sister				/* 判断hash类型是否存在 */
(integer) 0
127.0.0.1:6379[1]> hexists family brother		
(integer) 1
127.0.0.1:6379[1]> hkeys family							/* 获取hash类型的所有key值 */
1) "brother"
2) "father"
3) "mother"
127.0.0.1:6379[1]> hvals family							/* 获取hash类型的所有value值 */
1) "zhangsan"
2) "wangwu"
3) "zhaoliu"
3.List类型

List类型类似java的双端队列,可以从两端插入和弹出。命令主要以l和r开头,表示从左端操作队列,从右端操作队列。包含从左插入、从右插入、从左弹出、从右弹出、移除某元素、插入某元素、长度获取。

127.0.0.1:6379[1]> lpush num 1 2 3 4 5 6  7 8 9 10    	/* 从list左侧依次插入数据 */
(integer) 10
127.0.0.1:6379[1]> rpush num 11 12 13 14 15				/* 从list右侧依次插入数据 */
(integer) 15
127.0.0.1:6379[1]> lrange num 0 -1						/* 获取list的列表 */
 1) "10"
 2) "9"
 3) "8"
 4) "7"
 5) "6"
 6) "5"
 7) "4"
 8) "3"
 9) "2"
10) "1"
11) "11"
12) "12"
13) "13"
14) "14"
15) "15"
127.0.0.1:6379[1]> lpop num								/* 从list左侧弹出数据 */
"10"
127.0.0.1:6379[1]> lpop num
"9"
127.0.0.1:6379[1]> rpop num								/* 从list右侧弹出数据 */
"15"
127.0.0.1:6379[1]> rpop num
"14"
127.0.0.1:6379[1]> rpop num
"13"
127.0.0.1:6379[1]> llen num								/* 获取list长度 */
(integer) 10
127.0.0.1:6379[1]> linsert num before 8 7				/* list中插入数据 */
(integer) 11
127.0.0.1:6379[1]> lrange num 0 -1
 1) "7"
 2) "8"
 3) "7"
 4) "6"
 5) "5"
 6) "4"
 7) "3"
 8) "2"
 9) "1"
10) "11"
11) "12"
127.0.0.1:6379[1]> lrem num 2 7							/* 移除list中的数值 */
(integer) 2
127.0.0.1:6379[1]> lrange num 0 -1
1) "8"
2) "6"
3) "5"
4) "4"
5) "3"
6) "2"
7) "1"
8) "11"
9) "12"
127.0.0.1:6379[1]> ltrim num 0 3						/* 截取list的特定长度 */
OK
127.0.0.1:6379[1]> lrange num 0 -1
1) "8"
2) "6"
3) "5"
4) "4"
4.Set类型

set与java的set类似,都是不包含相同元素。命令以s开头,包含对集合的添加、删除、查询、是否存在、大小获取、并集、差集、合集运算。

127.0.0.1:6379[1]> sadd set 1 2 3 4 5 6 7 8 9 0			/* set中添加元素 */
(integer) 10
127.0.0.1:6379[1]> sadd set 1 2 3 4 5					/* set已有元素不会重复添加 */
(integer) 0
127.0.0.1:6379[1]> srem set 1 2 3 10					/* 移除set存在的元素 */
(integer) 3
127.0.0.1:6379[1]> scard set							/* 查询set的大小 */
(integer) 7
127.0.0.1:6379[1]> smembers set							/* 查询set中的元素 */
1) "0"
2) "4"
3) "5"
4) "6"
5) "7"
6) "8"
7) "9"
127.0.0.1:6379[1]> sismember set 1						/* 判断set中是否包含某元素 */
(integer) 0
127.0.0.1:6379[1]> sismember set 0		
(integer) 1
127.0.0.1:6379[1]> spop set 1							/**/
1) "6"
127.0.0.1:6379[1]> scard set
(integer) 6
127.0.0.1:6379[1]> sadd set2 1 2 3 4 5 6 7 8 9 0
(integer) 10
127.0.0.1:6379[1]> sdiff set set2
(empty list or set)
127.0.0.1:6379[1]> sinter set set2
1) "0"
2) "4"
3) "5"
4) "7"
5) "8"
6) "9"
127.0.0.1:6379[1]> sunion set set2
 1) "0"
 2) "1"
 3) "2"
 4) "3"
 5) "4"
 6) "5"
 7) "6"
 8) "7"
 9) "8"
10) "9"
5.Zset类型

Zset是带权重的set,不允许有相同的元素,每个元素都带有对应权重。命令以z开头,包含元素添加,删除、查询、大小获取、权重查询。

127.0.0.1:6379> zadd performance 36 zhangsan 60 li 75 wangwu 88 zhaoliu 	/* 有序集合添加元素 */
(integer) 4
127.0.0.1:6379> zrange performance 0 -1						/* 以下标位置,查询所有元素 */
1) "zhangsan"
2) "li"
3) "wangwu"
4) "zhaoliu"
127.0.0.1:6379> zcount performance 0 -1						/* 以score查询元素数量 */
(integer) 0
127.0.0.1:6379> zcount performance 0 100	
(integer) 4
127.0.0.1:6379> zrangebyscore performance 0 100				/* 以score,查询元素 */
1) "zhangsan"
2) "li"
3) "wangwu"
4) "zhaoliu"
127.0.0.1:6379> zrangebyscore performance 60 100
1) "li"
2) "wangwu"
3) "zhaoliu"
127.0.0.1:6379> zrem performance zhaoliu					/* 有序集合移除元素 */
(integer) 1
127.0.0.1:6379> zrange performance 0 100
1) "zhangsan"
2) "li"
3) "wangwu"
127.0.0.1:6379> zcard performance							/* 查询总数 */
(integer) 3
127.0.0.1:6379> zscore performance zhangsan					/* 查询某元素的分数 */
"36"
127.0.0.1:6379> zincrby performance 24 zhangsan				/* 增加某元素的分数 */
"60"
127.0.0.1:6379> zscore performance zhangsan
"60"
127.0.0.1:6379> zincrby performance -24 zhangsan			/* 减少某元素的分数 */
"36"

四、redis三种特殊类型

1.Geo类型

坐标类型。命令以geo开头,也可使用zset的部分命令。包含地理坐标的添加、删除、数量查询、地址的坐标查询、地址间距离查询、坐标附近的地址查询。

127.0.0.1:6379> geoadd china 116.41667 39.91667 beijing 121.43333 34.50000 shanghai
(integer) 2
127.0.0.1:6379> geoadd china 113.23333 23.16667 guangzhou 114.06667 22.61667 shenzhen
(integer) 2
127.0.0.1:6379> geoadd china 111 11 hubei					/* geo添加地理坐标 */
(integer) 1
127.0.0.1:6379> zrem china hubei							/* geo使用zset的命令移除坐标地址*/
(integer) 1
127.0.0.1:6379> zcard china									/* 查询geo地理坐标总数 */
(integer) 4
127.0.0.1:6379> geodist china beijing shanghai km			/* 查询两坐标的距离 */
"748.3469"
127.0.0.1:6379> geopos china beijing						/* 查询某地址的坐标 */
1) 1) "116.41667157411575"
   2) "39.916670952735892"
127.0.0.1:6379> zrange china 0 -1							/* 查询所有坐标 */
1) "guangzhou"
2) "shenzhen"
3) "shanghai"
4) "beijing"
127.0.0.1:6379> georadius china 110 23 1000 km withcoord  	/* 查询某坐标1000公里内的城市 */
1) 1) "guangzhou"
   2) 1) "113.23332935571671"
      2) "23.166670823726726"
2) 1) "shenzhen"
   2) 1) "114.06667023897171"
      2) "22.616669283525248"
127.0.0.1:6379> georadius china 110 23 1000 km withcoord withdist
1) 1) "guangzhou"
   2) "331.3496"
   3) 1) "113.23332935571671"
      2) "23.166670823726726"
2) 1) "shenzhen"
   2) "419.1123"
   3) 1) "114.06667023897171"
      2) "22.616669283525248"
127.0.0.1:6379> georadiusbymember china beijing 1000 km withcoord withdist /* 查询某城市1000公里内的城市 */
1) 1) "shanghai"
   2) "748.3469"
   3) 1) "121.43333047628403"
      2) "34.499999717161309"
2) 1) "beijing"
   2) "0.0000"
   3) 1) "116.41667157411575"
      2) "39.916670952735892"
2.Hyperloglogs类型

基数统计类型,适用于set类型的特殊场景。命令以pf开头,包含元素的添加、数量统计、合并。

127.0.0.1:6379> pfadd over10 11 12 13 14 15 16 17 18 19 20  	/* 基数统计添加元素 */
(integer) 1
127.0.0.1:6379> pfadd lower15 15 14 13 12 11 10 9 8 7 6 5
(integer) 1
127.0.0.1:6379> pfcount over10									/* 统计数量 */
(integer) 10
127.0.0.1:6379> pfcount lower15
(integer) 11
127.0.0.1:6379> pfmerge over10 lower15							/* 合并后一个统计到前一个统计中 */
OK
127.0.0.1:6379> pfcount over10
(integer) 16
127.0.0.1:6379> pfcount lower15
(integer) 11
127.0.0.1:6379>
3.Bitmap类型

bitmap类型类似布尔值,,只能设置为0或1。命令包含bit,有设置、获取、数量获取。

127.0.0.1:6379> setbit gotowork 1 1     					/* 设置周一有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 2 1							/* 设置周二有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 3 1							/* 设置周三有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 4 1							/* 设置周四有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 5 1							/* 设置周五有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 6 0							/* 设置周六没有去上班 */
(integer) 0
127.0.0.1:6379> setbit gotowork 7 0							/* 设置周日没有去上班 */
(integer) 0
127.0.0.1:6379> getbit gotowork 1							/* 查看周一是否去上班 */
(integer) 1
127.0.0.1:6379> getbit gotowork 7
(integer) 0
127.0.0.1:6379> bitcount gotowork 0  -1						/* 查看去上班的总数 */
(integer) 5

五、redis事务与乐观锁

1.事务

redis事务,使用multi命令表示开启事务,后面的命令进入队列,执行exec命令,则执行队列中的命令,执行discard命令,则取消执行队列中的命令。redis事务只是将命令放入到队列中,通过批量执行或取消执行,并不具备关系型数据库事务的特征。

127.0.0.1:6379> multi										/* 开启事务 */
OK
127.0.0.1:6379> set a 1										/* 命令一进入队列 */
QUEUED
127.0.0.1:6379> set b 2										/* 命令二进入队列 */
QUEUED
127.0.0.1:6379> set c 3										/* 命令三进入队列 */
QUEUED
127.0.0.1:6379> exec										/* 执行命令 */
1) OK
2) OK
3) OK
127.0.0.1:6379> multi										/* 开启事务 */
OK
127.0.0.1:6379> set d 4										/* 命令一进入队列 */
QUEUED
127.0.0.1:6379> set e 5										/* 命令二进入队列 */
QUEUED
127.0.0.1:6379> set f 6										/* 命令三进入队列 */
QUEUED
127.0.0.1:6379> discard										/* 回滚命令 */
OK
127.0.0.1:6379> get d
(nil)
127.0.0.1:6379> get a
"1"
2.乐观锁

redis乐观锁命令watch。先使用watch命令开始观察元素是否发生改变,然后使用multi开启事务,当观察的元素发生改变时,事务中的命令不执行,当观察的元素没发生改变时,事务中的命令执行。即使事务中操作的元素不包含被观察的元素,依然遵循上述规则。

127.0.0.1:6379> watch test									/* 观察元素 */
OK
127.0.0.1:6379> multi										/* 开启事务 */
OK
127.0.0.1:6379> set test 123								/* 命令一进入队列 */
QUEUED
127.0.0.1:6379> set test 234								/* 命令二进入队列 */
QUEUED
127.0.0.1:6379> exec										/* 执行命令,返回nil,元素发生了改变,事务中的命令未执行 */
(nil)	
127.0.0.1:6379> get test									
"345"
127.0.0.1:6379> unwatch										/* 释放观察 */
OK
127.0.0.1:6379> watch test
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> unwatch
OK

六、redis发布与订阅

redis的发布和订阅类似微信公众号的推文。订阅了公众号的人都会受到推文。包含subscribe订阅,publish推送消息,unsubscribe退订。redis的发布与订阅不能进行持久化,因此在5.0版本引入了stream
下面分别演示订阅了qqchannel和wxchannel推送消息。

1.订阅wxchannel
127.0.0.1:6379> subscribe wxchannel							/* 订阅微信渠道wxchannel */
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "wxchannel"
3) (integer) 1
1) "message"
2) "wxchannel"
3) "i am ykq"
2.订阅qqchannel
127.0.0.1:6379> subscribe qqchannel							/* 订阅qq渠道qqchannel */
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "qqchannel"
3) (integer) 1
1) "message"
2) "qqchannel"
3) "i am 18 years old"
3.推送消息
127.0.0.1:6379> publish wxchannel "i am ykq"				/* 推送给微信渠道消息 */
(integer) 1
127.0.0.1:6379> publish qqchannel "i am 18 years old"		/* 推送给qq渠道消息 */
(integer) 1

七、主从复制

使用两个端口启动两个redis-server,使用slaveof命令即可实现本次启动的两个服务实现主从。不过这种只是短暂的,本次生效,不是永久的。

1.启动服务6379
E:\redis>redis-server.exe redis.windows.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 8828
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[8828] 19 Jan 13:45:35.875 # Server started, Redis version 3.2.100
[8828] 19 Jan 13:45:35.876 * DB loaded from disk: 0.001 seconds
[8828] 19 Jan 13:45:35.876 * The server is now ready to accept connections on port 6379
2.复制redis.windows.conf

此处只安装一个redis,通过两个配置文件来启动两个服务,复制redis.windows.conf,命名为redis.windows1.conf
修改配置文件配置

port 6380							### 修改端口为6380
slaveof 127.0.0.1 6379				### 修改6380服务从属于6379服务
masterauth yinkeqi					### 修改主机验证的密码,主机有密码情况下,不配置将会复制失败
3.启动服务6380
E:\redis>redis-server.exe redis.windows1.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6380
 |    `-._   `._    /     _.-'    |     PID: 2720
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[2720] 19 Jan 14:06:38.591 # Server started, Redis version 3.2.100
[2720] 19 Jan 14:06:38.593 * DB loaded from disk: 0.001 seconds
[2720] 19 Jan 14:06:38.593 * The server is now ready to accept connections on port 6380
[2720] 19 Jan 14:06:38.593 * Connecting to MASTER 127.0.0.1:6379
[2720] 19 Jan 14:06:38.663 * MASTER <-> SLAVE sync started
[2720] 19 Jan 14:06:38.663 * Non blocking connect for SYNC fired the event.
[2720] 19 Jan 14:06:38.664 * Master replied to PING, replication can continue...
[2720] 19 Jan 14:06:38.664 * Partial resynchronization not possible (no cached master)
[2720] 19 Jan 14:06:38.720 * Full resync from master: 75a8bfd22d1551a3c28b72cfd44ee3ff40859341:1
[2720] 19 Jan 14:06:39.418 * MASTER <-> SLAVE sync: receiving 763 bytes from master
[2720] 19 Jan 14:06:39.424 * MASTER <-> SLAVE sync: Flushing old data
[2720] 19 Jan 14:06:39.425 * MASTER <-> SLAVE sync: Loading DB in memory
[2720] 19 Jan 14:06:39.427 * MASTER <-> SLAVE sync: Finished with success
4.客户端连接6379进行写操作

可以看到主机是可以进行读写的。

E:\redis>redis-cli.exe -p 6379 -a yinkeqi
127.0.0.1:6379> set name yinkeqi
OK
127.0.0.1:6379> get name
"yinkeqi"
5.客户端连接6380进行读操作

从机只能进行读操作,不能进行写操作。

E:\redis>redis-cli.exe -p 6380 -a yinkeqi
127.0.0.1:6380> get name
"yinkeqi"
127.0.0.1:6380> set name zhangsan
(error) READONLY You can't write against a read only slave.

八、哨兵模式

1.复制redis.windows.conf

哨兵模式需要三个节点演示,一个主节点A,两个从节点B、C。当主节点A下线了,其中一个从节点B升级为主节点,另一个从节点C的主机变为节点B。
因此需要再复制一个配置文件,命名为redis.windows2.conf

port 6381							### 修改端口为6381
slaveof 127.0.0.1 6379				### 修改6381服务从属于6379服务
masterauth yinkeqi					### 修改主机验证的密码,主机有密码情况下,不配置将会复制失败
2.配置三个sentinel.conf

配置三个哨兵,当有两个哨兵认为主机下线,则选举其中一个从机为主机

(1)sentinel.conf
port 9736                                       ### 指定当前哨兵的端口
sentinel monitor mymaster 127.0.0.1 6379 2		### 指定当前哨兵监控的主机ip和端口,以及判定主机下线条件
sentinel down-after-milliseconds mymaster 3000  ### 当主机3秒无响应,当前哨兵认为主机下线
sentinel auth-pass mymaster yinkeqi			### 当主机有密码时,需要设置连接主机的密码
(2)sentinel1.conf
port 9737
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster yinkeqi
(3)sentinel2.conf
port 9738
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster yinkeqi
3.启动三个redis服务
(1)6379服务
E:\redis>redis-server.exe redis.windows.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 13876
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[13876] 20 Jan 09:50:21.655 # Server started, Redis version 3.2.100
[13876] 20 Jan 09:50:21.657 * DB loaded from disk: 0.001 seconds
[13876] 20 Jan 09:50:21.657 * The server is now ready to accept connections on port 6379
[13876] 20 Jan 09:50:52.531 * Slave 127.0.0.1:6380 asks for synchronization
[13876] 20 Jan 09:50:52.531 * Full resync requested by slave 127.0.0.1:6380
[13876] 20 Jan 09:50:52.532 * Starting BGSAVE for SYNC with target: disk
[13876] 20 Jan 09:50:52.580 * Background saving started by pid 22388
[13876] 20 Jan 09:50:54.257 # fork operation complete
[13876] 20 Jan 09:50:54.258 * Background saving terminated with success
[13876] 20 Jan 09:50:54.266 * Synchronization with slave 127.0.0.1:6380 succeeded
[13876] 20 Jan 09:51:22.617 * Slave 127.0.0.1:6381 asks for synchronization
[13876] 20 Jan 09:51:22.617 * Full resync requested by slave 127.0.0.1:6381
[13876] 20 Jan 09:51:22.618 * Starting BGSAVE for SYNC with target: disk
[13876] 20 Jan 09:51:22.662 * Background saving started by pid 25956
[13876] 20 Jan 09:51:23.313 # fork operation complete
[13876] 20 Jan 09:51:23.314 * Background saving terminated with success
[13876] 20 Jan 09:51:23.319 * Synchronization with slave 127.0.0.1:6381 succeeded
(2)6380服务
E:\redis>redis-server.exe redis.windows1.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6380
 |    `-._   `._    /     _.-'    |     PID: 28308
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[28308] 20 Jan 09:50:52.458 # Server started, Redis version 3.2.100
[28308] 20 Jan 09:50:52.459 * DB loaded from disk: 0.001 seconds
[28308] 20 Jan 09:50:52.460 * The server is now ready to accept connections on port 6380
[28308] 20 Jan 09:50:52.460 * Connecting to MASTER 127.0.0.1:6379
[28308] 20 Jan 09:50:52.529 * MASTER <-> SLAVE sync started
[28308] 20 Jan 09:50:52.529 * Non blocking connect for SYNC fired the event.
[28308] 20 Jan 09:50:52.530 * Master replied to PING, replication can continue...
[28308] 20 Jan 09:50:52.531 * Partial resynchronization not possible (no cached master)
[28308] 20 Jan 09:50:52.581 * Full resync from master: 1e31e28f3f28670ed40f8dd165fc451ef6ee324e:1
[28308] 20 Jan 09:50:54.264 * MASTER <-> SLAVE sync: receiving 75 bytes from master
[28308] 20 Jan 09:50:54.268 * MASTER <-> SLAVE sync: Flushing old data
[28308] 20 Jan 09:50:54.268 * MASTER <-> SLAVE sync: Loading DB in memory
[28308] 20 Jan 09:50:54.272 * MASTER <-> SLAVE sync: Finished with success
(3)6381服务
E:\redis>redis-server.exe redis.windows2.conf
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6381
 |    `-._   `._    /     _.-'    |     PID: 16380
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[16380] 20 Jan 09:51:22.542 # Server started, Redis version 3.2.100
[16380] 20 Jan 09:51:22.543 * DB loaded from disk: 0.001 seconds
[16380] 20 Jan 09:51:22.544 * The server is now ready to accept connections on port 6381
[16380] 20 Jan 09:51:22.544 * Connecting to MASTER 127.0.0.1:6379
[16380] 20 Jan 09:51:22.615 * MASTER <-> SLAVE sync started
[16380] 20 Jan 09:51:22.615 * Non blocking connect for SYNC fired the event.
[16380] 20 Jan 09:51:22.616 * Master replied to PING, replication can continue...
[16380] 20 Jan 09:51:22.617 * Partial resynchronization not possible (no cached master)
[16380] 20 Jan 09:51:22.663 * Full resync from master: 1e31e28f3f28670ed40f8dd165fc451ef6ee324e:43
[16380] 20 Jan 09:51:23.318 * MASTER <-> SLAVE sync: receiving 75 bytes from master
[16380] 20 Jan 09:51:23.322 * MASTER <-> SLAVE sync: Flushing old data
[16380] 20 Jan 09:51:23.324 * MASTER <-> SLAVE sync: Loading DB in memory
[16380] 20 Jan 09:51:23.326 * MASTER <-> SLAVE sync: Finished with success
4.启动三个哨兵
(1)9736哨兵
E:\redis>redis-server.exe sentinel.conf --sentinel
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 9736
 |    `-._   `._    /     _.-'    |     PID: 30480
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[30480] 21 Jan 16:28:11.895 # Sentinel ID is beb9b509fefd0bfcd0d7a58a9956b094cef12503
[30480] 21 Jan 16:28:11.895 # +monitor master mymaster 127.0.0.1 6379 quorum 2
[30480] 21 Jan 16:28:11.898 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[30480] 21 Jan 16:28:11.901 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
[30480] 21 Jan 16:28:52.969 * +sentinel sentinel e6f45d87cc07b47c280c21d7676a360df2b220f8 127.0.0.1 9737 @ mymaster 127.0.0.1 6379
[30480] 21 Jan 16:29:19.947 * +sentinel sentinel 4f1ced8a0d327b1002a98b5614ec253bedd17a24 127.0.0.1 9738 @ mymaster 127.0.0.1 6379
[30480] 21 Jan 16:29:19.955 # +tilt #tilt mode entered
(2)9737哨兵
E:\redis>redis-server.exe sentinel1.conf --sentinel
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 9737
 |    `-._   `._    /     _.-'    |     PID: 21708
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[21708] 21 Jan 16:28:50.898 # Sentinel ID is e6f45d87cc07b47c280c21d7676a360df2b220f8
[21708] 21 Jan 16:28:50.899 # +monitor master mymaster 127.0.0.1 6379 quorum 2
[21708] 21 Jan 16:28:50.903 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:28:50.905 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:28:52.780 * +sentinel sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:28:56.922 # +sdown sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:29:17.265 * +sentinel sentinel 4f1ced8a0d327b1002a98b5614ec253bedd17a24 127.0.0.1 9738 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:29:20.041 # -sdown sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
[21708] 21 Jan 16:29:53.289 # +sdown sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
(3)9738哨兵
E:\redis>redis-server.exe sentinel2.conf --sentinel
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.100 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 9738
 |    `-._   `._    /     _.-'    |     PID: 17728
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[17728] 21 Jan 16:29:15.183 # Sentinel ID is 4f1ced8a0d327b1002a98b5614ec253bedd17a24
[17728] 21 Jan 16:29:15.184 # +monitor master mymaster 127.0.0.1 6379 quorum 2
[17728] 21 Jan 16:29:15.187 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
[17728] 21 Jan 16:29:15.189 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
[17728] 21 Jan 16:29:15.557 * +sentinel sentinel e6f45d87cc07b47c280c21d7676a360df2b220f8 127.0.0.1 9737 @ mymaster 127.0.0.1 6379
[17728] 21 Jan 16:29:20.088 * +sentinel sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
[17728] 21 Jan 16:29:53.408 # +sdown sentinel beb9b509fefd0bfcd0d7a58a9956b094cef12503 127.0.0.1 9736 @ mymaster 127.0.0.1 6379
5.客户端操作
(1)关闭6379服务
E:\redis>redis-cli.exe -p 6379 -a yinkeqi
127.0.0.1:6379> shutdown
(2)查看6380服务主从信息

6380服务被选举为主机

E:\redis>redis-cli.exe -p 6380 -a yinkeqi
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=13232,lag=0
master_repl_offset:13232
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:13231
(3)查看6381服务主从信息

6381服务的主机切换为了6380

E:\redis>redis-cli.exe -p 6381 -a yinkeqi
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:1
master_sync_in_progress:0
slave_repl_offset:21896
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

九、redis配置文件详解

######################   网络配置   ######################
bind 127.0.0.1 									### 绑定本机ip,只允许本地连接
requirepass yinkeqi								### 设置当前redis服务的密码
protected-mode yes								### 启动保护模式,校验bind的ip以及密码,关闭则不校验
port 6379										### 设置服务端口

######################   主从配置   ######################    
databases 16									### 设置数据库的数量,默认为0数据库
slaveof 127.0.0.1 6379 							### 设置本机为6379服务的从机
masterauth yinkeqi								### 当设置slaveof后,如果主机有密码必须设置主机密码,否则无法复制
daemonize yes									### windows不支持,指定该服务为后台守护进程,必须kill才能关闭,关闭服务窗口不会关闭服务
pidfile /var/run/redis.pid						### windows不支持,指定保存redis的进程id的文件

######################   rdb存储    ######################
dir ./											### 指定rdb保存目录
dbfilename dump.rdb								### 指定rdb方式持久化的文件名
rdbcompression yes								### rdb持久化时,是否进行压缩处理
save 900 1										### 每900秒有一次更新就保存
save 300 10										### 每300秒有10次更新就保存
save 60 10000									### 每60秒有10000次更新就保存

######################   aof存储    ######################
appendonly yes 									### 开启aof存储模式
appendfilename "appendonly.aof"					### 设置aof存储的文件名
appendfsync everysec							### 每秒进行一次持久化
# 	appendfsync no								### 不进行持久化,仅在系统需要时持久化
# 	appendfsync always							### 每次操作都进行持久化

######################   限制配置	######################
maxclients 10000								### 最大的客户端连接数
maxmemory <bytes>								### 最大的内存容量
maxmemory-policy noeviction						### 达到最大内存时的删除策略
#	volatile-lru	->	使用lru算法(最近最少使用算法)删除有过期时间的键
#	allkeys-lru		->	使用lru算法删除任何键(包含设置了过期时间和没设置过期时间的键)
#	volatile-random	->	随机删除带有过期时间的的键
#	allkeys-random	-> 	随机删除任意键
#	volatile-ttl	->	删除过期时间最近的键
#	noeviction		->	不删除键,返回错误,提示无法写入
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值