0%

redis集群缓存数据库

一、安装

1. docker安装

  • 拉取镜像
1
docker pull redis
  • 启动镜像
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. 慢语句

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#开头的所有key展示出来
# 结果里面就是没有,然后返回的第一个参数是下一个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
type key
  • 示例
1
2
127.0.0.2:50034> type BUS#PROXY_EVENTS
stream

三、配置解析

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将网络的收发分到了多线程上面去,而数据库的读写计算还是在单线程上。大致逻辑如下:

  1. epoll的io模型不变,主线程读取待接收的fd,分发到各个io线程进行读取,主线程进行等待
  2. 等待io线程读取完成,主线程再操作所有的io线程里面读完的数据,执行数据库的读写,这一步是单线程
  3. 读取数据操作完成,将要写的数据再次分发到各个io线程进行写回
  4. 主线程等待io线程写操作完成后,在重新回到1进行