redis笔记

你说的曾经没有我的故事 提交于 2020-02-23 03:30:49

Redis是开源的免费的高效的以键值对类型的 NoSQL数据库;

Redis自身优势:

1.支持的数据类型丰富;
2.因为使用的是内存,读写速度快;
3.原子性,redis中的操作都是单线程,但后期可能会出多线程;
4高可用,redis主从模式,哨兵,集群
5.可设置过期时间,消息订阅等

Redis支持的数据类型:

String(字符串)、List(列表)、Set(无序去重集合)、Sorted Set(有序去重集合)、hash(哈希)

Redis数据淘汰策略:

noeviction 不允许淘汰数据,内存满返回错误信息;
allkeys-lru 在所有数据列表中挑选调用最少的数据淘汰;
volatile-lru 在已经过期的数据列表中淘汰使用最少的数据;
allkeys-random 在所有数据列表中随机淘汰数据
volatile-random 在已经过期的数据列表中随机淘汰数据
volatile-ttl 在已经过期的数据列表中优先淘汰回收存活时间较短的数据;

Redis的value值最大存储1个G, String类型最大存储512GB;
Redis为了达到最快的读写速度,将数据都写入内存中,在通过异步的方式将数据持久化到磁盘中;这是Redis的优势;

Redis的持久化方案: (默认)RDB AOF

RDB: 是定期将数据快照保存在一个rbd文件中,当再次重启时就加载rbd文件恢复数据, 可在配置文件中设置: 在多少时间内,触发多少数据改变,就进行一个数据快照;
优势:

  1. 对性能影响小,每次保存快照都会分一个子进程来进行操作,不会影响其他处理操作;
  2. 恢复数据块,特别是恢复大量数据时;
  3. 可靠性高,保存的数据快照文件通过其他手段保存,是一个非常可靠的灾难性恢复手段;
    劣势:
    因为是定期保存数据快照,所以可能会发生少量数据丢失的情况;

**AOF:**将对redis执行的操作命令都记录下来,重启时将命令在重新执行一次;
有三种配置:
一种是交由系统自己决定;
二种:每一个命令都记录下来,数据最安全,但也是最影响性能;
三种:每秒同步一次

每一个操作都会记录,容易出现无用的数据,且文件过大,数据恢复慢;所以redis的退出AOF日志重写,会记录AOF日志的大小,当大小超过设置的大小后会进行日志重写,清空之前的数据;
优势:
1.数据安全,就算是每秒执行一个同步,最多也只丢失1秒的数据,损失小;
2.日志可读,易修改,当执行了某个错误的操作,只要日志没有重写,将日志找出来,删掉错误的指令,可以进行恢复;
缺点:
1.文件会比RDB文件大
2.在进行日志重写需要用到主进程,性能消耗比RDB大
3.数据恢复没有RDB快;

Redis的缓存穿透

当请求查询的key在缓存和数据库中都不存在,如果多次重复访问会造成数据库的压力增大;
解决:
1.将查询为空的数据也缓存在redis中,并设置一个过期时间,当数据更新时是,在清空这个key的缓存;
2.设置过滤器,将所有key都存入一个过滤器中,请求先由过滤器判断,如果存在就继续查询缓存,如果不存在就直接返回空,

Redis的缓存击穿

当请求查询的key在缓存中不存在热点数据过期,在数据库中有,但是如果当时很多个用户访问,在一个并发的情况下对数据库造成的压力;
解决
1.对热点数据不设置过期时间;
2.通过加锁来控制对数据库的查询;

Redis的缓存雪崩

大量key过期,或者是redis宕机,数据库压力增加;
解决:
1.避免大量key同时过期,将key的过期时间均匀设置,热点key不设置过期时间;
2.宕机,设置redis集群,实现redis的高可用避免出现宕机没有缓存的情况;

Redis的缓存一致性:

多个用户同时更新缓存数据时,会发生并发问题
弱一致性解决方案:
先更新数据库数据,在清空缓存数据;
强一致性解决:
更新查询只要是对数据库操作都加锁;

热点数据

如果确定热点数据?
对key的访问数量记录,使用redis中的sorted set 来存储这些key的访问数据量并排序;

缓存代码与业务分离

  • 应用直接写数据至数据库
  • canal 同步 binlog 至 MQ
  • 应用方监听 MQ,来修改缓存

Redis性能测试:

redis-benchmark [参数] [参数值]是官方自带的测试工具;
-h 指定服务器主机名 127.0.0.1
-p 指定服务器端口 6379
-s 指定服务器 socket
-c 指定并发连接数 50
-n 指定请求数 10000
-d 以字节的形式指定 SET/GET 值的数据大小 2
-k 1=keep alive 0=reconnect 1
-r SET/GET/INCR 使用随机 key, SADD 使用随机值
-P 通过管道传输 请求 1
-q 强制退出 redis。仅显示 query/sec 值
–csv 以 CSV 格式输出
-l 生成循环,永久执行测试
-t 仅运行以逗号分隔的测试命令列表。
-I Idle 模式。仅打开 N 个 idle 连接并等待。

启动redis执行./redis-benchmark -t get -n 100000 -c 100 -d 2048
测试get请求方式 100000的请求数 并发连接数100 数据大小2048字节(2KB)
最后一行可以看出QPS(每秒查询率)

QPS RT TPS
RT :响应时间
TPS 吞吐量
QPS 每秒查询率

Redis的主从配置

一个主库,从库连接主库只需要在配置文件中加上slaveof host(i地址) port(端口号) 例如:slaveof 192.168.200.129 6379
主库用来写操作,多从库负责读操作, 从库可以赋值主库的数据,从库不可以进行写操作;
主从复制中的主从服务器双方的数据库将保存相同的数据,概念上将这种现象称作数据库状态一致

Redis数据同步;

redis2.8之前的同步使用的是SYNC非常消耗性能;
redis2.8之后使用PSYNC,具有完整重同步和部分重同步两种模式。
完整重同步:
如果是初次复制同步就将RDB文件发送从库同步,如果不是就只需要将缓存区中的增量命令发送从库同步,会根据情况自动选择;
部分重同步:
将断线后的写命令放入缓存区,连接上后将断线期间的命令发送从库同步;

Redis主从同步过程;

分为快照同步与增量同步。首次同步采用快照同步,后续同步采用增量同步,如果网络断开,后来恢复连接时,对比主从服务器的复制偏移量,
如果相同代表这个就是之前断掉的主库,继续实行增量同步;
如果大于从库的复制偏移量就将主库数据缓冲区的命令进行同步,在进行增量同步,
中间间隔较长导致复制积压缓冲区中这部分指令已经丢失,这时只能再次快照同步;

Sentinel(哨兵)实现高可用

Sentine使用乒乓机制来监视主从服务器,
Sentine在redis的安装包中有,修改配置文件可以直接使用;
参数说明:
sentinel monitor mymaster 192.168.200.129 6379 3
mymaster 主节点名,可以任意起名,但必须和后面的配置保持一致。
192.168.200.129 6379 主节点连接地址。
3 将主服务器判断为失效需要投票,这里设置至少需要 3个 Sentinel 同意。
sentinel down-after-milliseconds mymaster 10000
设置Sentinel认为服务器已经断线所需的毫秒数。
sentinel failover-timeout mymaster 60000
设置failover(故障转移)的过期时间。当failover开始后,在此时间内仍然没有触发任何failoer操作,当前sentinel 会认为此次failoer失败,一般发生这个情况就是数据过大,在故障转移的过期时间内没有完成,就代表故障转移失败。
sentinel parallel-syncs mymaster 1
设置在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小,表示同时进行同步的从服务器越少,那么完成故障转移所需的时间就越长。

Sentinel主要是监控服务器的状态,并决定是否进行故障转移。但是在故障转移之前Sentinel是如何判断服务是否下线呢,主要分为主观下线和客观下线:

主观下线:

概念
主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例
对服务器做出的下线判断;
特点
如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时
间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复, 那么
Sentinel 就会将这个服务器标记为主观下线;

客观下线

概念
多个 Sentinel 实例在对同一个服务器做出 SDOWN (主管下线)判断, 并且通过SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下
线判断ODOWN(客观下线)。 (一个Sentinel 可以通过向另一个 Sentinel 发送命令来询问对方是否认为给定的服务器已下线)
特点
从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法
(strong quorum algorithm),而是使用了流言传播(Gossip): 如果
Sentinel在给定的时间范围内, 从其他Sentinel那里接收到了足够数量的主
服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为
客观下线。

注意点
客观下线条件只适用于主服务器,对于其他类型的 Redis 实例, Sentinel
在将它们判断为下线前不不需要进行协商, 所以从服务器或者其他
Sentinel 不会达到客观下线条件。 只要一个 Sentinel 发现某个主服务器进
入了客观下线状态, 这个Sentinel就可能会被其他 Sentinel 推选出,并对
失效的主服务器执行自动故障迁移操作;

Sentinel三大工作任务

监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel
可以通过API向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时,Sentinel会开始一次自动故障转移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器。当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器

设置Redis密码(保证redis的安全)

在所有的redis配置文件redis.conf中,
添加如下配置:
在Sentinel哨兵的配置文件sentinel01.conf中添加以下设置:
设置密码 requirepass 123456
设置访问主服务器密码 masterauth 123456
在Sentinel哨兵的配置文件sentinel01.conf中添加以下设置:
./redis-cli -h 192.168.200.129 -p 6381 -a 123456
-a就是设置访问密码;

Redis集群

集群架构特点:

  1. 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  2. 节点的fail是通过集群中超过半数的master节点检测失效时才生效。
  3. 客户端与redis节点直连,不需要连接集群所有节点,只需要连接集群中任意可用节点即可。
  4. 集群把所有的物理节点映射到[0-16383]slot上,cluster 负责维护
    node<>slot<>key关系
    在前面的特点中,最后一个node<>slot<>key关系是什么意思呢?
    这里是说数据是如何放到集群的节点中。Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分哈希槽。可以使用命令查看集群信息:
    ./redis-cli -p 7001(端口号) cluster nodes | grep master
哈希槽的使用:
  1. 集群搭建的时候分配哈希槽到节点上
  2. 使用集群的时候,先对数据key进行CRC16的计算
  3. 对计算的结果求16384的余数,得到的数字范围是0~16383
  4. 根据余数找到对应的节点(余数对应的哈希槽在哪个节点)
  5. 跳转到对应的节点,执行命令
    这种结构很容易添加或者删除节点。比如果我想新添加节点node4, 我需要从节点node1, node2, node3中得部分槽到node4上. 如果我想移除节点node1,需要将node1中的槽移到node2和node3节点上,然后将没有任何槽的node1节点从集群中移除即可。
    由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不不会造成集群不可用的状态。
    Redis 集群的主从复制模型
    为了使部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有一个或多个复制品。

Redis保证不了数据的强一致性;

twemproxy实现hash分片

twemproxy介绍
Twemproxy由Twitter开源,是一个redis和memcache快速/轻量级代理服务器,利用中间件做分片的技术。twemproxy处于客户端和服务器的中间,将客户端发来的请求,进行一定的处理后(sharding),再转发给后端真正的redis服务器。
官方网址:https://github.com/twitter/twemproxy
作用:
Twemproxy通过引入一个代理层,可以将其后端的多台Redis或Memcached实例进行统一管理与分配,使应用程序只需要在Twemproxy上进行操作,而不用关心后面具体有多少个真实的Redis或Memcached存储
特性
支持失败节点自动删除
可以设置重新连接该节点的时间
可以设置连接多少次之后删除该节点
减少客户端直接与服务器的连接数量
自动分片到后端多个redis实例上
多种哈希算法
md5,crc16,crc32,crc32a,fnv1_64,fnv1a_64,fnv1_32,fnv1a_32,
hsieh,murmur,jenkins
多种分片算法
ketama(一致性hash算法的一种实现),modula,random

使用场景分别使用。

单机版:数据量,QPS不大的情况使用
主从复制:需要读写分离,高可用的时候使用
Sentinel哨兵:需要自动容错容灾的时候使用
内置集群:数据量比较大,QPS有一定要求的时候使用,但集群节点不能过多
twemproxy集群:数据量,QPS要求非常高,可以使用

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!