目录
一、Redis相关
1、Redis简介
Redis(Remote Dictionary Server ),即远程字典服务,是一种支持主从同步的ey-value存储系统存储系统。是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
redis是一个key-value存储系统存储系统。它支持存储的value类型:string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型数据类型)都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
2、Redis特点
Redis 与其他 key - value 缓存产品有以下三个特点:
-
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
-
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
-
Redis支持数据的备份,即master-slave模式的数据备份。
3、Redis 优势
-
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
-
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
-
原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
-
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
二、集群搭建
1、docker-compose文件编写
<span style="background-color:#f8f8f8"><span style="color:#333333">version: <span style="color:#aa1111">'2'</span>
services:
master:
image: redis
container_name: redis-master
command: redis-server <span style="color:#0000cc">--requirepass</span> <span style="color:#116644">123456</span>
ports:
<span style="color:#0000cc">-</span> <span style="color:#aa1111">"6379:6379"</span>
networks:
sentinel-master:
ipv4_address: <span style="color:#116644">192</span>.169.0.2
slave1:
image: redis
container_name: redis-slave-1
ports:
<span style="color:#0000cc">-</span> <span style="color:#aa1111">"6380:6379"</span>
command: redis-server <span style="color:#0000cc">--slaveof</span> redis-master <span style="color:#116644">6379</span> <span style="color:#0000cc">--requirepass</span> <span style="color:#116644">123456</span> <span style="color:#0000cc">--masterauth</span> <span style="color:#116644">123456</span>
depends_on:
<span style="color:#0000cc">-</span> master
networks:
sentinel-master:
ipv4_address: <span style="color:#116644">192</span>.169.0.3
slave2:
image: redis
container_name: redis-slave-2
ports:
<span style="color:#0000cc">-</span> <span style="color:#aa1111">"6381:6379"</span>
command: redis-server <span style="color:#0000cc">--slaveof</span> redis-master <span style="color:#116644">6379</span> <span style="color:#0000cc">--requirepass</span> <span style="color:#116644">123456</span> <span style="color:#0000cc">--masterauth</span> <span style="color:#116644">123456</span>
depends_on:
<span style="color:#0000cc">-</span> master
networks:
sentinel-master:
ipv4_address: <span style="color:#116644">192</span>.169.0.4
networks:
sentinel-master:
driver: bridge
ipam:
config:
<span style="color:#0000cc">-</span> subnet: <span style="color:#116644">192</span>.169.0.0/16</span></span>
2、运行集群
<span style="background-color:#f8f8f8"><span style="color:#333333">[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker-compose up -d</span>
Creating network <span style="color:#aa1111">"redis_clusters_sentinel-master"</span> with driver <span style="color:#aa1111">"bridge"</span>
Creating redis-master ... <span style="color:#770088">done</span>
Creating redis-slave-1 ... <span style="color:#770088">done</span>
Creating redis-slave-2 ... <span style="color:#770088">done</span>
[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker-compose ps</span>
Name Command State Ports
<span style="color:#0000cc">-------------------------------------------------------------------------------</span>
redis-master docker-entrypoint.sh redis ... Up <span style="color:#116644">0</span>.0.0.0:6379->6379/tcp
redis-slave-1 docker-entrypoint.sh redis ... Up <span style="color:#116644">0</span>.0.0.0:6380->6379/tcp
redis-slave-2 docker-entrypoint.sh redis ... Up <span style="color:#116644">0</span>.0.0.0:6381->6379/tcp
[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker ps</span>
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
acdfccf7f0b4 redis <span style="color:#aa1111">"docker-entrypoint.s…"</span> <span style="color:#116644">16</span> seconds ago Up <span style="color:#116644">14</span> seconds <span style="color:#116644">0</span>.0.0.0:6381->6379/tcp redis-slave-2
76b74b0a640f redis <span style="color:#aa1111">"docker-entrypoint.s…"</span> <span style="color:#116644">16</span> seconds ago Up <span style="color:#116644">14</span> seconds <span style="color:#116644">0</span>.0.0.0:6380->6379/tcp redis-slave-1
f0ec343bc3b4 redis <span style="color:#aa1111">"docker-entrypoint.s…"</span> <span style="color:#116644">16</span> seconds ago Up <span style="color:#116644">15</span> seconds <span style="color:#116644">0</span>.0.0.0:6379->6379/tcp redis-master</span></span>
3、进入集群
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#aa5500"># 进入master节点</span>
[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker exec -it f0ec343bc3b4 bash</span>
root@f0ec343bc3b4:/data<span style="color:#aa5500"># redis-cli</span>
<span style="color:#116644">127</span>.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
<span style="color:#116644">127</span>.0.0.1:6379> ahth <span style="color:#116644">123456</span>
(error) ERR unknown command <span style="color:#009900">`ahth`</span>, with args beginning with: <span style="color:#009900">`123456`</span>,
<span style="color:#116644">127</span>.0.0.1:6379> auth <span style="color:#116644">123456</span>
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
(empty array)
<span style="color:#aa5500"># 进入master节点 > 设置key/value</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#770088">set</span> name dyl
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#3300aa">get</span> name
<span style="color:#aa1111">"dyl"</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#770088">exit</span>
root@f0ec343bc3b4:/data<span style="color:#aa5500"># exit</span>
<span style="color:#aa5500"># 进入slave1节点</span>
[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker exec -it 76b74b0a640f bash</span>
root@76b74b0a640f:/data<span style="color:#aa5500"># redis-cli</span>
<span style="color:#116644">127</span>.0.0.1:6379> auth <span style="color:#116644">123456</span>
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#aa5500"># 进入slave2节点 > 查看key/value</span>
[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker exec -it acdfccf7f0b4 bash</span>
root@acdfccf7f0b4:/data<span style="color:#aa5500"># redis-cli</span>
<span style="color:#116644">127</span>.0.0.1:6379> auth <span style="color:#116644">123456</span>
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#3300aa">get</span> name
<span style="color:#aa1111">"dyl"</span>
<span style="color:#116644">127</span>.0.0.1:6379>
</span></span>
三、Redis中的六大数据结构
https://www.cnblogs.com/xrq730/p/8944539.html
1、string数据类型
string 是Redis的最基本的数据类型,可以理解为与 Memcached 一模一样的类型,一个key 对应一个 value。string 类型是二进制安全的,意思是 Redis 的 string 可以包含任何数据,比如图片或者序列化的对象,一个 redis 中字符串 value 最多可以是 512M。
命令 | 描述 | 用法 |
---|---|---|
SET | (1)将字符串值Value关联到Key (2)Key已关联则覆盖,无视类型 (3)原本Key带有生存时间TTL,那么TTL被清除 | SET key value [EX seconds] [PX milliseconds] [NX|XX] |
GET | (1)返回key关联的字符串值(2)Key不存在返回nil (3)Key存储的不是字符串,返回错误,因为GET只用于处理字符串 | GET key |
MSET | (1)同时设置一个或多个Key-Value键值对 (2)某个给定Key已经存在,那么MSET新值会覆盖旧值 (3)如果上面的覆盖不是希望的,那么使用MSETNX命令,所有Key都不存在才会进行覆盖 (4)MSET是一个原子性操作,所有Key都会在同一时间被设置,不会存在有些更新有些没更新的情况 | MSET key value [key value ...] |
MGET | (1)返回一个或多个给定Key对应的Value(2)某个Key不存在那么这个Key返回nil | MGET key [key ...] |
SETEX | (1)将Value关联到Key(2)设置Key生存时间为seconds,单位为秒 (3)如果Key对应的Value已经存在,则覆盖旧值 (4)SET也可以设置失效时间,但是不同在于SETNX是一个原子操作,即关联值与设置生存时间同一时间完成 | SETEX key seconds value |
SETNX | (1)将Key的值设置为Value,当且仅当Key不存在(2)若给定的Key已经存在,SEXNX不做任何动作 | SETNX key value |
APPEND | 字符串追加 | APPEND key value |
DEL | 删除key | DEL key [key ...] |
<span style="background-color:#f8f8f8"><span style="color:#333333">[root@iZp06cqz6zbn9jZ redis_clusters]<span style="color:#aa5500"># docker exec -it 5a1cc01437ff bash</span>
root@5a1cc01437ff:/data<span style="color:#aa5500"># redis-cli</span>
<span style="color:#116644">127</span>.0.0.1:6379> auth <span style="color:#116644">123456</span>
OK
<span style="color:#116644">127</span>.0.0.1:6379> kyes *
(error) ERR unknown command <span style="color:#009900">`kyes`</span>, with args beginning with: <span style="color:#009900">`*`</span>,
<span style="color:#116644">127</span>.0.0.1:6379> keys *
(empty array)
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#770088">set</span> string1 dyl1
OK
<span style="color:#116644">127</span>.0.0.1:6379>
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"string1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#3300aa">get</span> string1
<span style="color:#aa1111">"dyl1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> mset string2 dyl2 string3 dyl3
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"string2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"string1"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"string3"</span>
<span style="color:#116644">127</span>.0.0.1:6379> mget string1 string2
<span style="color:#116644">1</span>) <span style="color:#aa1111">"dyl1"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"dyl2"</span>
<span style="color:#116644">127</span>.0.0.1:6379> setex strtime <span style="color:#116644">10</span> time1
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"string2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"string1"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"strtime"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"string3"</span>
十秒钟之后再次输入
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"string2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"string1"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"string3"</span>
<span style="color:#116644">127</span>.0.0.1:6379> append string1 <span style="color:#116644">123</span>
(integer) <span style="color:#116644">7</span>
<span style="color:#116644">127</span>.0.0.1:6379> <span style="color:#3300aa">get</span> string1
<span style="color:#aa1111">"dyl1123"</span>
<span style="color:#116644">127</span>.0.0.1:6379> del string3
(integer) <span style="color:#116644">1</span>
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"string2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"string1"</span>
</span></span>
2、hash数据类型
3、list数据类型
ist 列表,它是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边),它的底层实际上是个链表。
命令 | 描述 | 用法 |
---|---|---|
LPUSH | (1)将一个或多个值value插入到列表key的表头 (2)如果有多个value值,那么各个value值按从左到右的顺序依次插入表头 (3)key不存在,一个空列表会被创建并执行LPUSH操作 (4)key存在但不是列表类型,返回错误 | LPUSH key value [value ...] |
LPUSHX | (1)将值value插入到列表key的表头,当且晋档key存在且为一个列表 (2)key不存在时,LPUSHX命令什么都不做 | LPUSHX key value |
LPOP | (1)移除并返回列表key的头元素 | LPOP key |
LRANGE | (1)返回列表key中指定区间内的元素,区间以偏移量start和stop指定 (2)start和stop都以0位底 (3)可使用负数下标,-1表示列表最后一个元素,-2表示列表倒数第二个元素,以此类推 (4)start大于列表最大下标,返回空列表 (5)stop大于列表最大下标,stop=列表最大下标 | LRANGE key start stop |
LREM | (1)根据count的值,移除列表中与value相等的元素 (2)count>0表示从头到尾搜索,移除与value相等的元素,数量为count (3)count<0表示从从尾到头搜索,移除与value相等的元素,数量为count (4)count=0表示移除表中所有与value相等的元素 | LREM key count value |
LSET | (1)将列表key下标为index的元素值设为value (2)index参数超出范围,或对一个空列表进行LSET时,返回错误 | LSET key index value |
LINDEX | (1)返回列表key中,下标为index的元素 | LINDEX key index |
LINSERT | (1)将值value插入列表key中,位于pivot前面或者后面 (2)pivot不存在于列表key时,不执行任何操作(3)key不存在,不执行任何操作 | LINSERT key BEFORE|AFTER pivot value |
LLEN | (1)返回列表key的长度(2)key不存在,返回0 | LLEN key |
LTRIM | (1)对一个列表进行修剪,让列表只返回指定区间内的元素,不存在指定区间内的都将被移除 | LTRIM key start stop |
RPOP | (1)移除并返回列表key的尾元素 | RPOP key |
RPOPLPUSH | 在一个原子时间内,执行两个动作:(1)将列表source中最后一个元素弹出并返回给客户端 (2)将source弹出的元素插入到列表desination,作为destination列表的头元素 | RPOPLPUSH source destination |
RPUSH | (1)将一个或多个值value插入到列表key的表尾 | RPUSH key value [value ...] |
RPUSHX | (1)将value插入到列表key的表尾,当且仅当key存在并且是一个列表 (2)key不存在,RPUSHX什么都不做 | RPUSHX key value |
-
栈 通过命令 lpush+lpop
-
队列 命令 lpush+rpop
-
有限集合 命令 lpush+ltrim
-
消息队列 命令 lpush+rpop
<span style="background-color:#f8f8f8"><span style="color:#333333">root@5a1cc01437ff:/data<span style="color:#aa5500"># redis-cli</span>
<span style="color:#116644">127</span>.0.0.1:6379> auth <span style="color:#116644">123456</span>
OK
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"int1"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"string2"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"string1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> del int1 string1 string2
(integer) <span style="color:#116644">3</span>
<span style="color:#116644">127</span>.0.0.1:6379> keys *
(empty array)
<span style="color:#116644">127</span>.0.0.1:6379> lpush list1 <span style="color:#116644">1</span>
(integer) <span style="color:#116644">1</span>
<span style="color:#116644">127</span>.0.0.1:6379> lpush list1 <span style="color:#116644">2</span>
(integer) <span style="color:#116644">2</span>
<span style="color:#116644">127</span>.0.0.1:6379> keys *
<span style="color:#116644">1</span>) <span style="color:#aa1111">"list1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> llen list1
(integer) <span style="color:#116644">2</span>
<span style="color:#116644">127</span>.0.0.1:6379> lindex list1 <span style="color:#116644">0</span>
<span style="color:#aa1111">"2"</span>
<span style="color:#116644">127</span>.0.0.1:6379> lindex list1 <span style="color:#116644">1</span>
<span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> lpop list1
<span style="color:#aa1111">"2"</span>
<span style="color:#116644">127</span>.0.0.1:6379> lindex list1 <span style="color:#116644">0</span>
<span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> llen list1
(integer) <span style="color:#116644">1</span>
<span style="color:#116644">127</span>.0.0.1:6379> lpush list1 <span style="color:#116644">2</span>
(integer) <span style="color:#116644">2</span>
<span style="color:#116644">127</span>.0.0.1:6379> rpop list1
<span style="color:#aa1111">"1"</span>
</span></span>
4、set数据类型
Redis 的 set 是 string 类型的无序、不可重复
集合。
使用场景:利用集合的交并
集特性,比如在社交领域,我们可以很方便的求出多个用户的共同好友,共同感兴趣的领域等。
命令 | 描述 | 用法 |
---|---|---|
SADD | 添加:sadd set1 1 2 3 | SADD key number [member ...] |
SCARD | 集合元素数量 | SCARD key |
SDIFF | 差集: sdiff set1 set2 集合set1与 set2的差集 | SDIFF key [key ...] |
SDIFFSTORE | (1)和SDIFF类似,但结果保存到destination集合而不是简单返回结果集 (2) destination如果已存在,则覆盖 | SDIFFSTORE destionation key [key ...] |
SINTER | 交集: sinter set1 set2 | SINTER key [key ...] |
SINTERSTORE | (1)和SINTER类似,但结果保存早destination集合而不是简单返回结果集 (2)如果destination已存在,则覆盖 (3)destination可以是key本身 | SINTERSTORE destination key [key ...] |
SISMEMBER | (1)判断member元素是否key的成员,0表示不是,1表示是 | SISMEMBER key member |
SMEMBERS | (1)返回集合key中的所有成员 (2)不存在的key被视为空集 | SMEMBERS key |
SMOVE | (1)原子性地将member元素从source集合移动到destination集合 (2)source集合中不包含member元素,SMOVE命令不执行任何操作,仅返回0 (3)destination中已包含member元素,SMOVE命令只是简单做source集合的member元素移除 | SMOVE source desination member |
SPOP | (1)移除并返回集合中的一个随机元素,如果count不指定那么随机返回一个随机元素 (2)count为正数且小于集合元素数量,那么返回一个count个元素的数组且数组中的元素各不相同 (3)count为正数且大于等于集合元素数量,那么返回整个集合 (4)count为负数那么命令返回一个数组,数组中的元素可能重复多次,数量为count的绝对值 | SPOP key [count] |
SRANDMEMBER | (1)如果count不指定,那么返回集合中的一个随机元素(2)count同上 | SRANDMEMBER key [count] |
SREM | 删除:移除集合中的一个或多个member元素,不存在的member将被忽略 | SREM key member [member ...] |
SUNION | 并集:sunion set1 set2 | SUNION key [key ...] |
SUNIONSTORE | (1)类似SUNION,但结果保存到destination集合而不是简单返回结果集 (2)destination已存在,覆盖旧值 (3)destination可以是key本身 | SUNION destination key [key ...] |
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#116644">127</span>.0.0.1:6379> sadd set1 <span style="color:#116644">1</span> <span style="color:#116644">2</span> <span style="color:#116644">3</span>
<span style="color:#116644">127</span>.0.0.1:6379> sadd <span style="color:#770088">set</span> <span style="color:#116644">2</span> <span style="color:#116644">3</span> <span style="color:#116644">4</span> <span style="color:#116644">5</span>
<span style="color:#116644">127</span>.0.0.1:6379> sdiff set1 <span style="color:#770088">set</span>
<span style="color:#116644">1</span>) <span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> sunion set1 <span style="color:#770088">set</span>
<span style="color:#116644">1</span>) <span style="color:#aa1111">"1"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"2"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"3"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"4"</span>
<span style="color:#116644">5</span>) <span style="color:#aa1111">"5"</span>
<span style="color:#116644">127</span>.0.0.1:6379> sinter <span style="color:#770088">set</span> set1
<span style="color:#116644">1</span>) <span style="color:#aa1111">"2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"3"</span>
<span style="color:#116644">127</span>.0.0.1:6379> srem <span style="color:#770088">set</span> <span style="color:#116644">4</span>
(integer) <span style="color:#116644">1</span>
<span style="color:#116644">127</span>.0.0.1:6379> smembers <span style="color:#770088">set</span>
<span style="color:#116644">1</span>) <span style="color:#aa1111">"2"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"3"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"5"</span>
</span></span>
5、zset数据类型
6、stream数据类型
基于Redis的Stream类型的完美消息队列解决方案 https://zhuanlan.zhihu.com/p/60501638
Redis和专业的消息队列如何选择? https://zhuanlan.zhihu.com/p/367452637
Redis 当作队列来使用时,始终面临的 2 个问题:
Redis 本身可能会丢数据
面对消息积压,Redis 内存资源紧张,Kafka、RabbitMQ 这类消息队列就不一样了,它们的数据都会存储在磁盘上
如果你的业务场景足够简单,对于数据丢失不敏感,而且消息积压概率比较小的情况下,把 Redis 当作队列是完全可以的,Redis 相比于 Kafka、RabbitMQ,部署和运维也更加轻量。
Redis Stream 是 Redis 5.0 版本新增加的数据结构。
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
-
简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
-
而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
关于redis讲的很好:https://www.jianshu.com/p/efae507f03cf
<span style="background-color:#f8f8f8"><span style="color:#333333"><span style="color:#116644">127</span>.0.0.1:6379> xadd codehole * name laoqian age <span style="color:#116644">30</span>
<span style="color:#aa1111">"1624075334164-0"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xadd codehole * name xiaoyu age <span style="color:#116644">29</span>
<span style="color:#aa1111">"1624075342341-0"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xadd codehole * name xiaoqian age <span style="color:#116644">1</span>
<span style="color:#aa1111">"1624075348213-0"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xlen codehole
(integer) <span style="color:#116644">3</span>
<span style="color:#116644">127</span>.0.0.1:6379> xrange codehole <span style="color:#0000cc">-</span> <span style="color:#981a1a">+</span>
<span style="color:#116644">1</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075334164-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"laoqian"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"30"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075342341-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoyu"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"29"</span>
<span style="color:#116644">3</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075348213-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoqian"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xrange codehole <span style="color:#116644">1624075342341</span><span style="color:#0000cc">-0</span> <span style="color:#981a1a">+</span>
<span style="color:#116644">1</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075342341-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoyu"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"29"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075348213-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoqian"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xrange codehole <span style="color:#116644">1624075348213</span><span style="color:#0000cc">-0</span> <span style="color:#981a1a">+</span>
<span style="color:#116644">1</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075348213-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoqian"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"1"</span>
<span style="color:#116644">127</span>.0.0.1:6379> xdel codehole <span style="color:#116644">1624075348213</span><span style="color:#0000cc">-0</span>
(integer) <span style="color:#116644">1</span>
<span style="color:#116644">127</span>.0.0.1:6379> xrange codehole <span style="color:#0000cc">-</span> <span style="color:#981a1a">+</span>
<span style="color:#116644">1</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075334164-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"laoqian"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"30"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"1624075342341-0"</span>
<span style="color:#116644">2</span>) <span style="color:#116644">1</span>) <span style="color:#aa1111">"name"</span>
<span style="color:#116644">2</span>) <span style="color:#aa1111">"xiaoyu"</span>
<span style="color:#116644">3</span>) <span style="color:#aa1111">"age"</span>
<span style="color:#116644">4</span>) <span style="color:#aa1111">"29"</span>
<span style="color:#116644">127</span>.0.0.1:6379> del codehole
(integer) <span style="color:#116644">1</span></span></span>
7、常用命令