瑞士“军刀”——redis的相关问题

瑞士“军刀”——redis的相关问题

Scroll Down

redis的相关问题

主要包括如何配置读写分离,淘汰策略、哨兵模式、集群、缓存问题等

1.redis的安装配置

1.安装

1.解压
2. yum install gcc-c++
3.make
4.make PREFIX=/usr/local/redis install
5.cp redis.conf /usr/local/redis

2.配置conf

1.后台启动,daemonize yes
2.指定数据存放路径,dir /usr/local/redis/log rdb存放的路径
3..requirepass 设置密码
4.bind 0.0.0.0

3.设置脚本启动 开启自动启动

1.find / -name redis_init_script
2.cp /opt/redis/utils/redis_init_script /etc/init.d/redis
3.vi /etc/init.d/redis
	修改redis的配置文件地址
	修改redis的客户端 服务端地址
	加入开机启动脚本
		#chkconfig: 22345 10 90
		#description: Start and Stop redis
	chkconfig redis on

image.png

打开redis命令:service redis start

关闭redis命令:service redis stop

2.redis持久化策略

RDB

RDB:快照 每隔一段时间拷贝全部指令 粗粒度

优点:
可以容灾,远程发送备份的rdb文件
在进行拷贝的时候,会fork一个子进程,子进程进行IO操作
原理:
隔时段形成指令的备份	
缺点:
最后一次保存操作宕机会丢失备份
子进程进行保存会占用内存

save 900 1
save 300 10
save 60 10000

image.png

AOF

AOF:每隔几秒追加的方式记录写的指令 细粒度

优点:
采用追加的方式日志记录指令
可读性强
缺点:
日志的体积会非常大
aof比RDB更慢

image.png

3.redis读写分离

1.主从配置

replicaof <masterip> <masterport> 主机ip端口
masterauth <master-password> 主机密码
默认主写从读

2.全量同步

第一次连接:

1)从服务器连接主服务器,发送SYNC命令; 
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

3.增量同步

第一次同步后:

Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

4.同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

5.同步问题

主从数据不一致:可能是主从的配置不一样(淘汰策略maxmemort)
主从数据延迟:网络延迟 IO延迟 

4.哨兵模式

1.配置与启动

sentinel.conf:

protected-mode no 保护模式关闭
port 26379
daemonize yes
pidfile /var/run/redis-sentinel.pid
dir "/usr/local/redis/6379" 修改工作目录
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
logfile "/usr/local/redis/6379/sentinel26379.log" # 添加指明日志文件名

启动:

redis-sentinel /usr/local/redis/6379/26379.conf 或者 redis-server /usr/local/redis/6379/26379.conf --sentinel
redis-sentinel /usr/local/redis/6380/26380.conf 或者 redis-server /usr/local/redis/6380/26380.conf --sentinel
redis-sentinel /usr/local/redis/6381/26381.conf 或者 redis-server /usr/local/redis/6381/26381.conf --sentinel

2.主观客观下线

”主观”失效,即当前sentinel实例认为某个redis服务为”不可用”状态.
“客观”失效,即多个sentinel实例都认为master处于”SDOWN”状态,那么此时master将处于ODOWN,ODOWN可以简单理解为master已经被集群确定为”不可用”,将会开启failover

5.redis集群

redis集群,是将节点平均分配0-16383的槽点位,分布的key是按hash算法计算到0-16383的槽位。
image.png

6.redis淘汰键策略

# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones with an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.

7.redis缓存问题

1.缓存雪崩

多个key同时失效

过期时间错开
部分keys永不过期
多缓存结合

2.缓存击穿

直接跳过redis查询数据库

1.将空查询也缓存 设置过期时间
2.布隆过滤器

3.redis与数据库内容不一致方案

延时双删 +设置缓存的过期时间
1)先删除缓存
2)再写数据库
3)休眠500毫秒(根据具体的业务时间来定)
4)再次删除缓存

4.redis做分布式锁

方案一:
Setnx locknx task
image.png
每个线程去setnx 返回是1的话 设置locknx时间 然后执行独占资源逻辑
存在线程获取到锁但是挂掉来不起expire
方案二:
SET key value [EX seconds][PX milliseconds][nx|xx]
EX second:设置键的过期时间为second秒
Px millisecond:设置键的过期时间为millionsecond毫秒
Nx:只在键不存在时,才对键进行设置操作 key存在创建失败 key不存在创建成功
Xx: 只在键存在时,才对键进行设置操作
Set操作成功完成时 返回OK 否则返回nil
image.png