一、Redis知识图谱整理:
二、 Redis常见问题整理:
- 1、Mysql驱动commit方法是否同步,如果同步,客户端先commit再更新缓存,是否不会出现缓存脏数据问题 -- 缓存的读写模式
只要在高并发场景下就会出现脏读问题,因为本质为不同的数据源,所以只能通过 延时双删 让一致性的事件尽量的短。
- 2、redis的bitmap模式实现位图的原理是什么,为什么位数很大也可以存储
Bitmap 的基本原理就是用一个 bit 来标记某个元素对应的 Value,而 Key 即是该元素。由于采用一个bit 来存储一个数据,因此可以大大的节省空间。
Java 中 int 类型占用 4 个字节,即 4 byte,又 1 byte = 8 bit,所以 一个 int 数字的表示大概如下,
试想以下,如果有一个很大的 int 数组,如 10000000,数组中每一个数值都要占用 4 个字节,则一共需要占用 10000000 * 4 = 40000000 个字节,即 40000000 / 1024.0 / 1024.0 = 38 M
如果使用 bit 来存放上述 10000000 个元素,只需要 10000000 个 bit 即可, 10000000 / 8.0 / 1024.0/ 1024.0 = 1.19 M 左右,可以看到 bitmap 可以大大的节约内存。
使用 bit 来表示数组 [1, 2, 5] 如下所示,可以看到只用 1 字节即可表示:
- 3、目前在互联网公司中哨兵和Redis集群哪个用的比较多?
都有使用,RedisCluster在5.0以后趋近于完美,很多公司使用的是Redis3的版本
所以还是用哨兵多些,对于新开发的产品选择RedisCluster的比较多
- 4、rediscluster迁移过程中,如果moved到a节点,a节点正在迁移,但是get的数据尚未迁移完成,是否会在a节点直接返回get的数据
是的,当一个槽被设置为 MIGRATING 状态时, 原来持有这个槽的节点仍然会继续接受关于这个槽的命令请求, 但只有命令所处理的键仍然存在于节点时, 节点才会处理这个命令请求。如果命令所使用的键不存在与该节点, 那么节点将向客户端返回一个 -ASK 转向(redirection)错误, 告知客户端, 要将命令请求发送到槽的迁移目标节点。
- 5、rediscluster的副本漂移功能是自动生效的么,是否需要进行配置
不需要,Redis通过周期性调度函数ClusterCorn来完成副本漂移
- 6、自动化缓存预热怎么做?
1. 数据量不大的情况下系统启动时加载
2. 定时刷新
3. 手动刷新
- 7、redis客户端分区,如果使用一致性hash环,添加节点后,数据迁移怎么做
redis客户端分区是Redis客户端自行实现分片算法的,所以需要手动迁移数据
可以直接拷贝rdb文件,这样数据会有冗余
可以使用move命令写脚本或数据迁移工具(redis-dump)
比较麻烦,所以用一致性hash环会初始化尽量多的节点。
- 8、哨兵是怎样实现修改redis配置文件的?
sentinel将选择出来的新的主机,修改redis.conf 去掉repliaof或slaveof
sentinel自己的sentinel.conf 修改sentinel monitor mymaster 新的主机IP和端口 2
如果原来的主机重新启动,则sentinel修改它的redis.conf加上repliaof 新的主机和端口或slaveof新的主机和端口
- 9、集群模式下需要做服务器之间的ssh免密登陆吗?
RedisCluster做密码设置:redis cluster设置密码有两种方式
1.在集群创建时,配置文件中添加如下两行
masterauth passwd
requirepass passwd
2.如果集群已经创建好,也可以动态设置密码 在集群的所有实例(包含主节点和从节点)中执行
config set masterauth 123456
config set requirepass 123456
auth 123456
config rewrite
方法二的效果和方法一是一样的,会在redis的配置文件中写入下面两行配置,并且配置立即生效,不需要重启redis。
masterauth 123456
requirepass 123456
在访问时,添加密码:
[root@localhost bin]# ./redis-cli -p 7001 -a '123456' -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:7001> set a2 111
-> Redirected to slot [11786] located at 192.168.72.128:7003
OK
192.168.72.128:7003> get a2
"111"
ssh免密登陆一般不使用,因为不安全,早期可以利用Redis的漏洞实现SSH免密登录,Redis5已经补上这个漏洞了。
- 10、redis集群中总线端口如何修改
每个Redis集群中的节点都需要打开两个TCP连接。一个连接用于正常的给Client提供服务,比如7001,还有一个额外的端口(通过在这个端口号上加10000)作为数据端口,比如17001。第二个端口(17001)用于集群总线,这是一个用二进制协议的点对点通信信道。这个集群总线(Cluster bus)用于节点的失败侦测、配置更新、故障转移授权,等等。客户端从来都不应该尝试和这些集群总线端口通信,它们只应该和正常的Redis命令端口进行通信。注意,确保在你的防火墙中开放着两个端口,否则,Redis集群节点之间将无法通信。
命令端口和集群总线端口的偏移量总是10000。
tcp 0 0 0.0.0.0:17001 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:17002 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:17003 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:17004 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:17005 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:17006 0.0.0.0:* LISTEN
- 11、redis锁怎么保证在事务提交后执行,如果锁释放了,事务还没提交怎么办
先获得分布式锁再操作,操作成功后释放锁
//加锁并设置有效期
if(redis.lock("RDL",200)){
//判断库存
if (orderNum<getCount()){
//加锁成功 ,可以下单
order(5);
//释放锁
redis,unlock("RDL");
}
}
- 12、及时聊天系统用发布订阅或者stream实现靠谱?
可以做
stream是Redis5.0后新增的数据结构,用于可持久化的消息队列。
几乎满足了消息队列具备的全部内容,包括:
1. 消息ID的序列化生成
2. 消息遍历
3. 消息的阻塞和非阻塞读取
4. 消息的分组消费
5. 未完成消息的处理
6. 消息队列监控
stream提供对消息历史记录的查询,所以也可以实现群聊
- 13、我在生成环境中有次被DDOS攻击,Redis积累了数据特别太多导致系统卡顿,但是明明都加了过期时间,不知道问题出在哪儿
1、过期策略的设置
2、Redis积累了数据特别太多在RDB时会fork时间过长,会阻塞主进程
3、DDOS是网络攻击,一般不会对数据产生影响
4、加一个prometheus对redis的监控,确定一下redis现在的状态
5、增加aof/rdb的执行周期或暂时关闭rdb/aof
三、 Redis详细得内容后续会持续整理更新(未完待续)
RedisCluster集群搭建整理:RedisCluster的安装、部署、扩容和 Java客户端调用