一.Redis基础知识
1. 端口6379的由来
6379 = Merz
Merz全名Alessia Merz,是意大利的一位广告女郎。
2. 默认数据库
默认有16个数据库,且初始状态默认选择0号数据库(即第一个数据库)。
3.数据库切换
可以使用select 进行数据库切换。
select 8 切换到8号数据库
4.密码管理
统一密码管理,所有库密码都一致。
5.查看key数量
dbsize-查看当前数据库的key数量。
6.清空当前库
flushdb-清空当前库。
7.清空所有库
flushall-清空所有库。
8.Redis单线程
为什么Redis是单线程且效率极高:
1).绝大部分请求是纯粹的内存操作。
2).避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑。各种锁的问题,不存在加锁释放锁操作。
3).使用IO多路复用技术,可以处理并发的连接。
二、Redis数据类型
1 key键
1. keys * 查看当前库中所有的key 。
2. exists key 判断某个key是否存在。
可以设置多个key,只返回存在的个数,但不返回哪一个存在/不存在。
exists k1 查看k1是否存在,如果存在返回1
exists k1 k2 k3 查看k1 k2 k3是否存在,如果k1 k2存在,k3不存在,则返回2
3. move key db 将当前数据库的 key 移动到给定的数据库 db 当中。
move k1 8 将k1从当前数据库移动到8号库
4. type key 查看当前key 所储存的值的类型。
返回当前key所储存的值的类型,如string 、list等。
5. del key 删除已存在的key,不存在的 key 会被忽略。
可以设置多个key,返回删除成功的个数。
del k1 删除k1,如果成功返回1,失败返回0
del k1 k2 k3 删除k1 k2 k3,如果k1 k2存在,k3不存在,则返回2
6. expire key time 给key设置time秒的过期时间。
设置成功返回 1 。 当 key 不存在返回 0。
expire k1 10 给k1设置10秒后过期
7. ttl key 以秒为单位返回 key 的剩余过期时间。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单
位,返回 key 的剩余生存时间。
8. persist key 移除给定 key 的过期时间,使得 key 永不过期。
当过期时间移除成功时,返回 1 。 如果 key 不存在或 key 没有设置过期时间,返回 0 。
2 五大数据类型-String(字符串)
2.1 简介
String是Redis最基本的类型,一个key对应一个value。
String是二进制安全的,意味着String可以包含任何数据,比如序列化对象或者一张图片。
String最多可以放512M的数据。
2.2 常用命令
1. set key value 用于设置给定 key 的值。如果 key 已经存储其他值, set 就重写旧值,且无视类
型。
set k1 v1 向Redis中设置一个k1的键值对
set k1 100 将k1的值由v1重置为100
2. get key 用于获取指定 key 的值。如果 key 不存在,返回 nil 。
3. append key value 将给定的value追加到key原值末尾。
如果 key 已经存在并且是一个字符串, append 命令将 value 追加到 key 原来的值的末尾。
如果 key 不存在, append 就简单地将给定 key 设为 value ,就像执行 set key value 一样。
append k1 v1 在Redis中不存在k1,所以直接设置k1的值为v1
append k1 v2 向k1的值末尾添加一个v2,最终结果为v1v2
4. strlen key 获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错
误。
5. setex key time value 给指定的 key 设置值及time 秒的过期时间。如果 key 已经存在, setex命
令将会替换旧的值,并设置过期时间。
setex k1 10 v1 向Redis中设置一个k1的键值对并且10秒后过期
6. setnx key value当key不存在时,设置给定 key 的值。如果key存在,则没有任何影响。
setnx k1 v1 向Redis中设置一个k1的键值对
setnx k1 v2 Redis中存在k1,则没有影响,k1的值仍然为v1
7. incr key 将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 incr 操作。
如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。
incr k1 因为Redis中不存在k1,所以先初始化为0,再递增,值为1
incr k1 存在k1,递增后k1的值为2
set k2 v2
incr k2 因为k2不为数值,Redis返回一个错误
8. decr key将 key 中储存的数字值减一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 decr 操作。
如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。
decr k1 因为Redis中不存在k1,所以先初始化为0,再递增,值为-1
decr k1 存在k1,递增后k1的值为-2
set k2 v2
decr k2 因为k2不为数值,Redis返回一个错误
9. incrby/decrby key step 将key存储的数字值按照step进行增减。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 incrby/decrby 命令。
如字符串类型的值不能表示为数字、或者是其他类型,那么返回一个错误。
10. mset key1 value1 key2 value2 ……同时设置一个或多个 key-value 。
mset k1 v1 k2 v2 k3 v3 同时向Redis中设置了k1 k2 k3
11. mget key1 key2 ……返回所有(一个或多个)给定 key 的值。
如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。
mget k1 k2 同时获取k1 k2
12. msetnx key1 value1 key2 value2 ……用于所有给定 key 都不存在时,同时设置一个或多个
key-value 。msetnx具有原子性特性,有一个失败,则都失败。
msetnx k1 v1 k2 v2 向Redis中设置k1 k2两个键值对
msetnx k1 v2 k3 v2 Redis中存在k1,k1设置失败,由于原子性特性,k3也设置失败
13. getrange key start end用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由
start 和 end 两个偏移量决定(包括 start 和 end 在内)。
set java helloworld 设置一个key为java,value为helloworld的值
getrange java 0 3 获取索引0-3的值,结果为hell
14. setrange key offset value用指定的字符串重写给定 key 所储存的字符串值,重写的位置从偏移量 offset 开始。
set java helloworld 设置一个key为java,value为helloworld的值
setrange java 5 baizhan 从偏移位置5(w)开始,用baizhan重写key
2.3 String底层数据结构
String底层数据结构是简单动态字符串(simple dynamic string,SDS)。
类似于JAVA中的ArrayList,采用预分配方式来减少内存的频繁分配。
如图,内存实际大小一般都要高于字符串实际大小。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时每次只会多扩1M的空间。字符串最大长度为512M。
3 五大数据类型-List(列表)
3.1 简介
List是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
底层是一个双向链表,对两段操作性能极高,通过索引操作中间的节点性能较差。
一个List最多可以包含 个元素 ( 每个列表超过40亿个元素)。
3.2 常用命令
1. lpush/ rpush key1 value1 value2 value3……从左边(头部)/右边(尾部)插入一个或多个
值。
lpush k1 v1 v2 v3 从左边放入v1 v2 v3
rpush k1 v4 v5 v6 从右边放入v4 v5 v6
2. lrange key start end返回key列表中的start和end之间的元素(包含start和end)。 其中 0 表示
列表的第一个元素,-1表示最后一个元素。
lrange k1 0 2 取出列表里前3个值,结果为v3 v2 v1
lrange k1 0 -1 取出列表里全部值,结果为v3 v2 v1 v4 v5 v6
3. lpop/rpop key移除并返回第一个值/最后一个值。
值在键在,值光键亡。
lpop k1 从列表中删除v3,并返回,当前列表全部值v2 v1 v4 v5 v6
rpop k1 从列表中删除v6,并返回,当前列表全部值v2 v1 v4 v5
4. lindex key index 获取列表index位置的值(从左开始)。
5. llen key获取列表长度。
6. lrem key count value从左边开始删除与value相同的count个元素。
lrem k1 2 v1 从左边开始删除k1列表中2个v1元素
7. linsert key before/after value newvalue 在列表中value值的前边/后边插入一个newvalue值
(从左开始)。
linsert k1 before v1 v5 在v1前面插入一个v5
8. lset key index value将索引为index的值设置为value
4 五大数据类型-Set(集合)
4.1 简介
与List类似是一个列表功能,但Set是自动排重的,当需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择。
Set是String类型的无序集合,它底层其实是一个value为null的hash表,所以添加、删除、查找的时间复杂度都是O(1)。
一般来说,一个算法如果是O(1),随着数据增加,查找数据的时间不变。
集合中最大的成员数为 ( 每个集合超过40亿个元素)。
4.2 常用命令
1. sadd key value1 value2……将一个或多个元素添加到集合key中,已经存在的元素将被忽略。
sadd k1 v1 v2 v2 v3 v4 v5 v6向集合中添加值,最终只有v1 v2 v3 v4 v5 v6
2. smembers key取出该集合的所有元素。
smembers k1
3. sismember key value判断集合key中是否含有value元素,如有返回1,否则返回0。
sismember k1 v1
4. scard key返回该集合的元素个数。
scard k1
5. srem key value1 value2……删除集合中的一个或多个成员元素,不存在的成员元素会被忽略。
srem k1 v1 v2 删除v1 v2
6. spop key随机删除集合中一个元素并返回该元素。
spop k1 随机删除一个元素,并返回
7. srandmember key count随机取出集合中count个元素,但不会删除。
srandmember k1 2 随机取出集合中的2个元素
8. smove sourcekey destinationkey value将value元素从sourcekey集合移动到destinationkey
集合中。如果 sourcekey集合不存在或不包含指定的 value元素,则 smove 命令不执行任何操作,仅返回 0。
smove k1 k2 v5 将元素v5从集合k1中移动到集合k2
9. sinter key1 key2返回两个集合的交集元素。
10. sunion key1 key2返回两个集合的并集元素。
11. sdiff key1 key2返回两个集合的差集元素(key1中的,不包含key2)
sinter k1 k2 返回v3
sunion k1 k2 返回v1 v2 v3 v4 v5
sdiff k1 k2 返回v1 v2
sdiff k2 k1 返回v4 v5
5 五大数据类型-Hash(哈希)
5.1 简介
Hash是一个键值对的集合。
Hash 是一个 String 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。每个 Hash 可以存储 键值对(40多亿)。
Hash存储结构优化
如果field数量较少,存储结构优化为类数组结构
如果field数量较多,存储结构使用HashMap结构
5.2 常用命令
1. hset key field value给key集合中的field赋值value。
如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
如果字段已经存在于哈希表中,旧值将被重写。
hset user name baizhan 创建一个key为user的哈希,并创建name字段,给name字段赋值为
baizhan
hset user age 3 在key为user的哈希中,创建age字段赋值为3
hset user name shangxuetang 将key为user的哈希name字段修改为shangxuetang
2. hget key field从key哈希中,取出field字段的值。
hget user name 从key为user的哈希中取出name字段的值,结果为shangxuetang
3. hmset key field1 value1 field2 value2……批量设置哈希的字段及值。
hmset user1 name bjsxt age 15 创建一个key为user1的哈希,有两个字段name和age
4. hexists key field 判断指定key中是否存在field
如果哈希表含有给定字段,返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。
hexists user name 返回1
5. hkeys key获取该哈希中所有的field。
6. hvals key获取该哈希中所有的value。
7. hincrby key field increment为哈希表key中的field字段的值加上增量increment。
增量也可以为负数,相当于对指定字段进行减法操作。
如果哈希表的 key 不存在,一个新的哈希表被创建并执行 hincrby 命令。
如果指定的字段不存在,那么在执行命令前,字段的值被初始化为 0 。
对一个储存字符串值的字段执行 hincrby 命令将造成一个错误。
hincrby user age 10 对user中的age字段做运算,增加10
8. hdel key field1 field2……删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。
返回被成功删除字段的数量,不包括被忽略的字段。
hdel user name age 删除user中的name和age字段
9. hsetnx key field value给key哈希表中不存在的的字段赋值 。
如果哈希表不存在,一个新的哈希表被创建并进行 hsetnx 操作。
如果字段已经存在于哈希表中,操作无效。
如果 key 不存在,一个新哈希表被创建并执行 hsetnx 命令。
hsetnx user name
6 五大数据类型-Zset(有序集合)
6.1 简介
Zset与Set非常相似,是一个没有重复元素的String集合。
不同之处是Zset的每个元素都关联了一个分数(score),这个分数被用来按照从低分到高分的方式排序集合中的元素。集合的元素是唯一的,但分数可以重复。
因为元素是有序的,所以可以根据分数(score)或者次序(position)来获取一个范围内的元素。
6.2 常用命令
1. zadd key score1 value1 score2 value2……将一个或多个元素(value)及分数(score)加入到
有序集key中。
如果某个元素已经是有序集的元素,那么更新这个元素的分数值,并通过重新插入这个元素,来保
证该元素在正确的位置上。
分数值可以是整数值或双精度浮点数。
如果有序集合 key 不存在,则创建一个空的有序集并执行 zadd 操作。
zadd k1 100 java 200 c++ 300 python 400 php
2. zrange key start end [withscores]返回key集合中的索引start和索引end之间的元素(包含start
和end)。
其中元素的位置按分数值递增(从小到大)来排序。 其中 0 表示列表的第一个元素,-1表示最后一个
元素。
withscores是可选参数,是否返回分数。
zrange k1 0 -1 返回集合中所有元素
zrange k1 0 -1 withscores 返回集合中所有元素,并携带元素分数
3. zrangebyscore key minscore maxscore [withscores]返回key集合中的分数minscore 和分数
maxscore 之间的元素(包含minscore 和maxscore )。其中元素的位置按分数值递增(从小到大)
来排序。
zrangebyscore k1 200 400 返回200-400分之间的元素递增排序
4. zrevrangebyscore key maxscore minscore [withscores]返回key集合中的分数maxscore和
分数minxscore 之间的元素(包含maxscore和minxscore )。其中元素的位置按分数值递减(从大
到小)来排序。
zrevrangebyscore k1 400 200 返回200-400分之间的元素递减法排序
5. zincrby key increment value为元素value的score加上increment的值。
zincrby k1 50 java 给java元素加上50分
6. zrem key value删除该集合下value的元素。
zrem k1 php 删除php
7. zcount key minscore maxscore统计该集合在minscore 到maxscore分数区间中元素的个数。
zcount k1 100 300 统计100分到300分中间元素的个数
8. zrank key value返回value在集合中的排名,从0开始。
zrank k1 c++ 返回c++排名
7 新数据类型-Bitmaps
7.1 简介
在计算机中,用二进制(位)作为存储信息的基本单位,1个字节等于8位。
例如 "abc" 字符串是由 3 个字节组成,计算机存储时使用其二进制表示,"abc"分别对应的ASCII码是97、98、99,对应的二进制是01100001、01100010、01100011,在内存中表示如下:
合理地使用 位 能够有效地提高内存使用率和开发效率。
Redis提供了Bitmaps这个 “数据结构” 可以实现对位的操作:
1. Bitmaps 本身不是一种数据结构,实际上它就是字符串(key 对应的 value 就是上图中的一串二进制),但是它可以对字符串的位进行操作。
2. Bitmaps 单独提供了一套命令,所以在 Redis 中使用 Bitmaps 和使用字符串的方法不太相同。可以把 Bitmaps 想象成一个以位为单位的数组,数组的每个单元只能存储 0 和 1,数组的下标在
Bitmaps中叫做偏移量。
7.2 常用命令
1. setbit key offset value设置Bitmaps中某个偏移量的值。
偏移量从0开始,且value值只能为0或1。
setbit sign 0 1 设置sign的第一位值为1
setbit sign 1 1 设置sign的第二位值为1
setbit sign 2 0 设置sign的第三位值为0
setbit sign 3 1 设置sign的第四位值为1
2. getbit key offset 获取Bitmaps中某个偏移量的值。
获取key的offset 的值。
getbit sign 3 获取偏移量为3的值,结果为1
如果偏移量未设置值,则也返回0。
getbit sign 99 获取偏移量为99的值,结果为0
3. bitcount key [start end]统计字符串被设置为1的bit数量。一般情况下,给定的整个字符串都会
被进行统计,可以选择通过额外的start和end参数,指定字节组范围内进行统计(包括start和
end),0表示第一个元素,-1表示最后一个元素。
bitcount sign 获取整个字符串被设置为1的bit数量,结果为3
如:当前存在一个key为k1的bitmaps存储着[00000001,00000001,00000010,00000011],分别对
应[1,1,2,3]。
setbit num 7 1
setbit num 15 1
setbit num 22 1
setbit num 30 1
setbit num 31 1
bitcount num 1 2 统计索引1、2两个字节组中bit=1的数量,即统计00000001,00000010中
bit=1的数量,结果为2
bitcount num 1 3 统计索引1、2、3三个字节组中bit=1的数量,即统计
00000001,00000010,00000011中bit=1的数量,结果为4
bitcount num 0 -1 统计所有的字节组中bit=1的数量,结果为5
setbit设置或获取的是bit(位)的位置,bitcount计算的是byte(字节)位置。
4. bitop and/or destkey sourcekey1 sourcekey2……将多个bitmaps通过求交集/并集方式合并成一个新的bitmaps。
bitop and k3 k1 k2 通过求交集将k1 k2合并成k3
bitop or k3 k1 k2 通过求并集将k1 k2合并成k3
8 新数据类型-Geospatia
8.1 简介
GEO,Geographic,地理信息的缩写。
该类型就是元素的二维坐标,在地图上就是经纬度。Redis基于该类型,提供了经纬度设置、查询、范围查询、距离查询、经纬度Hash等常见操作。
8.2 常用命令
1. geoadd key longitude latitude member [longitude latitude member ..……]用于存储指定
的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到
指定的 key 中。
geoadd chinacity 116.405285 39.904989 beijing 将北京的经纬度和名称添加到chinacity
geoadd chinacity 104.065735 30.659462 chengdu 121.472644 31.231706 shanghai
将成都和上海的经纬度、名称添加到chinacity
有效的经度:-180 ~ +180 有效的纬度:-85.05 ~ +85.05,当设置的经度纬度值超过范围会报错。
两级无法直接添加。
一般会直接下载城市数据,直接通过java程序直接一次性导入。
2. geopos key member [member ……]**从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。
geopos chinacity shanghai beijing 返回chinacity中名称为shanghai和beijing的经纬度
3. geodist key member1 member2 [m|km|ft|mi]用于返回两个给定位置之间的距离。
最后一个距离单位参数说明:
- m :米,默认单位。
- km :千米。
- mi :英里。
- ft :英尺。
geodist chinacity shanghai beijing 返回shanghai和beijing之间的距离,结果
1067597.9668,单位米
geodist chinacity shanghai chengdu km 返回shanghai和chengdu之间的距离,结果
1660.0198,单位是千米
4. georadius key longitude latitude radius m|km|ft|mi 以给定的经纬度(longitude latitude)为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离(radius )的所有位置元素。
georadius chinacity 116 40 1200 km 获取经纬度116 40为中心,在chinacity内1200公里
范围内的所有元素。结果shanghai beijing
9 新数据类型-Hyperloglog
9.1 简介
在我们做站点流量统计的时候一般会统计页面UV(独立访客:unique visitor)和PV(即页面浏览量:page view)。
什么是基数?
数据集{1,2,5,7,5,7,9},那么这个数据集的基数集为{1,2,5,7,9},基数(不重复元素)为5,基数估计就是在误差可接受范围内,快速计算基数。
如果是通过Redis来处理,我们可以使用String类型然后自增计数即可达到统计PV,统计UV可以使用Set,每个用户id是唯一的可以放到这个集合里。
以上方案虽然结果准确,但随着数据不断增加,导致占用的内存空间越来越大,对于非常大的数据集是不合适的。
Hyperloglog 是一种基数估算统计,在输入元素的数量特别巨大时,计算基数所需的空间是固定的,并且很小。
在Redis中,每个Hyperloglog 只占用12KB内存,就可以计算接近 个不同元素的基数。
因为HyperLogLog 只会更具输入元素来计算基数,而不会存储输入元素本身,所以Hyperloglog 不能像集合那样,返回输入的各个元素。
9.2 常用命令
1. pfadd key element1 element2……将所有元素参数添加到 Hyperloglog 数据结构中。
如果至少有个元素被添加返回 1, 否则返回 0。
pfadd book1 java c++ 添加两个元素,当前book1数量为2
pfadd book1 java php 添加一个元素,当前book1数量为3
2. pfcount key1 key2……计算Hyperloglog 近似基数,可以计算多个Hyperloglog ,统计基数总
数。
pfcount book1 计算book1的基数,结果为3
pfadd book2 chinese math 添加两个元素到book2中
pfcount book1 book2 统计两个key的基数总数,结果为5
3. pfmerge destkey sourcekey1 sourcekey2……将一个或多个Hyperloglog(sourcekey1) 合并成一个Hyperloglog (destkey )。
比如每月活跃用户可用每天活跃用户合并后计算。
pfmerge book book1 book2 将book1和book2合并成book,结果为5
10 Redis配置文件详解
10.1 units单位
配置大小单位,开头定义基本度量单位,只支持bytes,大小写不敏感。
10.2 #### INCLUDES
Redis只有一个配置文件,如果多个人进行开发维护,那么就需要多个这样的配置文件,这时候多个配置文件就可以在此通过 include /path/to/local.conf 配置进来,而原本的 redis.conf 配置文件就作为一个总闸。
10.3 #### NETWORK
1. bind:绑定redis服务器网卡IP,默认为127.0.0.1,即本地回环地址。访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。
2. protected-mode:本机保护模式,值为yes时只能本机访问不能远程访问。
3. port:指定redis运行的端口,默认是6379。
4. timeout:设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。默认值为0,表示不关闭。
10.4 #### GENERAL
1. daemonize:设置为yes表示指定Redis以守护进程的方式启动(后台启动)。
2. pidfile:配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到
/var/redis/run/redis_6379.pid 文件里面。
3. loglevel :定义日志级别。默认值为notice,有如下4种取值:
- debug(记录大量日志信息,适用于开发、测试阶段)。
- verbose(较多日志信息)。
- notice(适量日志信息,使用于生产环境)。
- warning(仅有部分重要、关键信息才会被记录)。
4. logfile :配置log文件地址,默认打印在命令行终端的窗口上。
5. databases:设置数据库的数目。
10.5 #### SECURITY
1. requirepass:设置redis连接密码。
比如: requirepass 123 表示redis的连接密码为123。
10.6 其他配置
1. maxclients :设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为
Redis进程可以打开的最大数量。 如果设置 maxclients为0 ,表示不作限制。当客户端连接数到达
限制时,Redis会关闭新的连接并向客户端返回错误信息。
2. maxmemory:设置Redis的最大内存,如果设置为0 。表示不作限制。通常是配合maxmemory-policy参数一起使用。
3. maxmemory-policy :当内存使用达到maxmemory设置的最大值时,redis使用的内存清除策
略。
清除策略包括:
- volatile-lru:利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
- allkeys-lru:利用LRU算法移除任何key
- volatile-random:移除设置过过期时间的随机key
- allkeys-random:移除随机key
- volatile-ttl:移除即将过期的key(minor TTL)
- noeviction:不移除任何key,只是返回一个写错误 ,默认选项
11 发布与订阅
11.1 什么是发布与订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
11.2 Redis的发布与订阅
1. 客户端订阅频道
2. 当给这个频道发送消息后,消息就会发送给订阅的客户端
3. Redis中发布与订阅命令
订阅:subscribe channel 订阅频道channel。
发布:publish channel msg向频道channel 发送一条msg消息。
11.3 发布与订阅命令行实现
1. 打开一个客户端订阅channel 1频道。
2. 打开另一个客户端给channel 1频道发送一条hello消息。
返回1代表订阅者数量。
3. 打开第一个客户端可以看到发送的消息