一、安装
1. docker安装
1 2 3 4 5 6
| docker run \ # 启动命令 --network bridge \ # 使用网桥运行 --rm \ # 停止后自动删除容器 -p 6379:6379 \ # 默认端口为6379,映射到外部6379 --name redis \ # 容器名称 redis # 镜像
|
二、命令详解
1. redis-cli
2. redis里面执行命令
2.1. slowlog 慢语句
1 2 3 4 5 6 7 8
| # 查询慢日志 127.0.0.2:50011> slowlog get 1 1) 1) (integer) 80 # 序号 2) (integer) 1699278803 # 时间戳 3) (integer) 11050 # 耗时,单位微秒 4) 1) "info" # 命令 5) "127.0.0.1:43688" # 客户端 6) ""
|
2.2. scan 扫描key
Redis——Scan原理与应用
语法
1
| scan cursor [MATCH pattern] [COUNT count] [TYPE type]
|
- 从cursor扫描匹配pattern的数据,扫描key的数量为count
- 不传MATCH,就是列举count个数据
- 传了MATCH,列举count个数据,将匹配到pattern的显示出来
- cursor首次传0,获取到的第一个参数就是cursor下一次遍历的位置,当cursor返回0说明全表扫描完毕
1 2 3 4 5 6 7 8 9 10 11
| # 扫描redis中10个key,符合SESS # 结果里面就是没有,然后返回的第一个参数是下一个cursor位置 127.0.0.2:50011> scan 0 MATCH SESS#* COUNT 10 1) "36" 2) (empty array)
# 再次传入cursor遍历查找就找到了要的结果 # cursor返回非0说明还有key没扫到 127.0.0.2:50011> scan 36 MATCH SESS#* COUNT 10 1) "54" 2) 1) "SESS#125f5a0f-8909-4fc5-968b-f0156a357ecb_e2354754-6a57-4f0d-8582-3e3fba9dee3b"
|
2.3. type 查看key类型
1 2
| 127.0.0.2:50034> type BUS#PROXY_EVENTS stream
|
2.4. xread 读取stream类型数据
1
| xread [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
|
示例,读取消息队列BUS#EVENTS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 127.0.0.2:50034> xread COUNT 5 STREAMS BUS#EVENTS 0 1) 1) "BUS#EVENTS" 2) 1) 1) "1712157305006-0" 2) 1) "k" 2) "{\"event\":\"ConfigChanged\"}" 2) 1) "1712157310008-0" 2) 1) "k" 2) "{\"event\":\"ConfigChanged\"}" 3) 1) "1712157315012-0" 2) 1) "k" 2) "{\"event\":\"ConfigChanged\"}" 4) 1) "1712157605015-0" 2) 1) "k" 2) "{\"event\":\"ConfigChanged\"}" 5) 1) "1712157610019-0" 2) 1) "k" 2) "{\"event\":\"ConfigChanged\"}"
|
三、配置解析
1. aof持久化
- aof储存的是redis的命令集,是恢复当前redis状态的命令
- 1s写入一次,丢失只有1s的指令丢失
- 随时间推移会越来越大,超过一定大小会进行优化,优化成当前状态的最小指令集
- 新版redis变成使用当前内存镜像和日志结合的方式进行备份
四、使用的几种思想
1. 持久化考虑
- 一般redis使用是作为缓存使用,并不作为持久化数据储存使用
- 使用持久化尽量考虑不要影响系统性能,影响系统性能就可能还不如使用mysql
- 尽量考虑缓存为重启可恢复,如果使用持久化就要考虑重启丢失部分数据的可能
2. 高性能和可靠性
- 两者不可兼得,追求高性能就不可能同时保证完全可靠
- 完全追求可靠,会导致redis的性能可能还会低于mysql
3. 一致性和可用性
- 强一致性: 集群保证每个节点数据一致,但是性能很低
- 弱一致性(默认): 可能丢数据
- 最终一致性: 存在一个强一致性黑盒,每个redis和此黑盒同步,如果redis挂掉,重启后从黑盒同步
4. 分布式锁
- 对数据一致性要求高,不可以使用redis做分布式锁,因为不可靠,如金融
- 对数据一致性要求不高,对处理速度要求更高,可以使用,如互联网非金融业务
五、源码解析
1. 线程模型
参考自Redis 多线程网络模型全面揭秘
老版本单线程io
1
| 对于一个 DB 来说,CPU 通常不会是瓶颈,因为大多数请求不会是 CPU 密集型的,而是 I/O 密集型。具体到 Redis 的话,如果不考虑 RDB/AOF 等持久化方案,Redis 是完全的纯内存操作,执行速度是非常快的,因此这部分操作通常不会是性能瓶颈,Redis 真正的性能瓶颈在于网络 I/O,也就是客户端和服务端之间的网络传输延迟,因此 Redis 选择了单线程的 I/O 多路复用来实现它的核心网络模型。
|
- 单线程模型,使用linux下的epoll实现多路复用的模式,实现不阻塞的高性能需求
- 每个读取和计算都在单个线程执行,防止很多hashmap的多线程不安全的操作
v6.0新版本多线程io,需要配置开启
单线程可以完成各种操作,为什么还要引入多线程。由于redis的性能瓶颈其实只是在网络的收发上面,并不是在数据库的操作上面。
redis将网络的收发分到了多线程上面去,而数据库的读写计算还是在单线程上。大致逻辑如下:
- epoll的io模型不变,主线程读取待接收的fd,分发到各个io线程进行读取,主线程进行等待
- 等待io线程读取完成,主线程再操作所有的io线程里面读完的数据,执行数据库的读写,这一步是单线程
- 读取数据操作完成,将要写的数据再次分发到各个io线程进行写回
- 主线程等待io线程写操作完成后,在重新回到1进行