Redis学习笔记

0、redis常用指令总结:Redis常用命令

1、Redis查看所有key的指令:keys *(生产环境禁止使用)

2、Redis发布订阅(publish/subscribe):Redis服务器只是作为各个客户端消息的中转站,记录哪个客户端订阅了哪些channel,可以认为服务器保存了一个消息转发的路由表;而Redis客户端订阅了一个channel后,会阻塞等待该channel的消息。

3、Redis持久化(Persistence)

(1)基本概念:将内存中的数据以某种形式同步到硬盘上;

(2)两种方式:

a、RDB方式:

通过快照(snapshot)完成,当符合一定条件Redis将内存中的所有数据生成一个副本文件保存到硬盘;

Redis会在以下情况进行快照:

  • 根据规则配置进行自动快照,也就是在一段时间内当发生改变的key的数量超过多少时会自动进行快照,Redis的配置中使用形如:save 900 1这样来指明如果900s内有1个key发生了变化,就自动执行快照;
  • 通过redis-cli执行save指令,即同步执行快照,快照过程中Redis会阻塞所有来自客户端的请求;或者bgsave指令,即后台异步执行快照,同时继续处理客户端的请求;
  • 通过redis-cli执行flushall指令,而且自动快照条件不为空;
  • 执行复制(replication)时,即设置了主从模式时,Redis会在复制初始化时进行快照;

快照文件存储路径:

Redis默认把快照文件保存在当前进程工作目录中的dump.rdb文件中,可通过配置dir和dbfilename来指定快照文件存储路径和文件名;

快照原理:

使用fork函数创建子进程,父进程负责继续接收处理客户端请求,而子进程将内存数据写入硬盘中的临时文件,写入完成后将该临时文件替换旧的RDB文件,至此快照完成;注意执行fork的时候,类Unix系统会使用写时复制技术,也即新的RDB文件存储的是执行fork时的内存数据;写时复制可以避免将内存数据复制两份,从而大大减少快照时占用的内存,但如果快照的过程中收到较多的写入请求,则此时Redis服务占用的内存会显著大于实际的内存数据大小。

注:由于快照过程中Redis并不会修改RDB文件,只有快照结束时才用临时文件替换旧的RDB文件,也即RDB文件任何时候都是完整的,因此可以通过定时备份RDB文件来实现Redis数据库备份;

通过RDB方式持久化,如果Redis异常退出,则会丢失最后一次快照以后更改的数据。

Redis启动后读取RDB文件(前提是没有启用AOF),将数据从硬盘载入内存,所需时间与数据量大小、数据结构、服务器性能相关;通常将一个1000万个字符串类型键,大小为1GB的RDB文件载入到内存需要20-30秒。

b、AOF方式:

(1)每执行一条会更改Redis中数据的命令,Redis会将该命令写入硬盘中的AOF文件;

(2)Redis默认没有启用AOF的持久化方式,可以通过修改配置appendonly参数为yes启用;

(3)AOF文件的保存路径与RDB文件相同,默认文件名为appendonly.aof,可以通过修改appendfilename参数更改;

(4)可以通过配置auto-aof-rewrite-percentage和auto-aof-rewrite-min-size参数使得Redis在一定条件下自动优化重写AOF文件;

(5)虽然每次执行更改数据库内容时,AOF都会将命令记录在AOF文件中,但是由于操作系统的缓存机制,数据还没有真正写入硬盘,而是进入系统的硬盘缓存,系统默认30秒执行一次同步操作,将硬盘缓存内容真正写入硬盘;而这需要Redis在写入AOF文件后主动要求系统将缓存内容同步到硬盘,可以通过appendfsync参数设置同步时机,Redis默认采用everysec,也即每秒同步一次,也可以设为always,也即每条写入命令都同步一次,这是最安全也是最慢的,也可以设为no,即完全交给系统来同步,默认30秒一次;

(6)当使用Redis存储非临时数据时,一般需要打开AOF来降低进程中止导致的数据损失;

 

4、Redis复制(replication)

基本概念:

就是主从复制,通过复制可以实现读写分离(把从数据库设置为只读),主要目的就是为了防止单点故障,可以看做是在线实时的冗余备份,当主服务器的数据更新后自动将更新的数据同步到从服务器中。

配置方法:

(1)一个Redis服务在启用时指定slaveof参数即可成为从服务器,例如:

redis-server --port 6380 --slaveof 127.0.0.1 6379

(2)而对于已经启动的Redis服务器(不管其为主服务器还是从服务器),则其客户端可以通过发送'slaveof 主服务器ip 主服务器端口'命令使得该服务器变为从服务器;如果该服务器已经是其他Redis服务器的从服务器,slaveof命令会停止和原来数据库的同步转而和新数据库同步;

(3)对于从服务器,其客户端可以通过slaveof no one命令把从服务器变为主服务器;

(4)从服务器默认是只读的;

复制过程:

(1)复制初始化阶段

  • 从服务器与主服务器建立socket连接后,首先向主服务器发送PING命令,如果主服务器没有在规定时间内发送PONG响应,则认为主服务器不可连接,则断开socket连接重连;
  • 从服务器得到PONG响应后,如果自身设置了认证,即masterauth选项,则发送AUTH命令,否则下一步;
  • 认证成功后,从服务器发送“REPLCONF listening-port 从服务器端口号”命令,向主服务器发送从服务器的端口;
  • 向主服务器发送PSYNC命令,
  • 主服务器收到PSYNC命令后,会在后台执行快照,并将快照期间接收到的命令缓存起来,快照完成后把快照文件和缓存一起发送给从服务器;
  • 从服务器接收后,载入快照文件并执行缓存的命令

(2)复制同步阶段

  • 主数据库执行的任何导致数据变化的命令都会异步传送给从数据库;
  • 只要执行复制,主服务器就会进行快照,即使已经关闭了RDB方式的持久化(通过删除所有save参数)
  • 心跳检测:从服务器默认每秒向主服务器发送命令:REPLCONF ACK <replication_offset>,其中replication_offset是从服务器当前的复制偏移量;心跳检测的意义是,检测主从服务器的网络连接,辅助实现min-slaves选项,检测命令丢失。

 

5、Redis哨兵(Sentinel)

基本概念:是一个独立的进程,专门负责监控Redis系统的运行状态。

哨兵的作用:

(1)监控主从数据库是否正常运行;

(2)主数据库出现故障时自动将从数据库切换为主数据库;

注:哨兵之间也可以互相监控。

启动sentinel命令:

redis-sentinel /path/to/your/sentinel.conf或者redis-server /path/to/your/sentinel.conf --sentinel

sentinel.conf文件的常见内容,配置需要监控的主数据库:

sentinel monitor master-name master-ip master-port quorum

工作原理:

(1)连接到主服务器(master)

Sentinel与主服务器创建两个异步连接,一个连接订阅主服务器的__sentinel__:hello频道,另一个连接用于发送和接收命令;

(2)获取主服务器信息

Sentinel默认每10秒向要监控的主服务器发送INFO命令,并通过分析返回的响应结果获取当前主服务器的信息;

(3)获取从服务器的信息

Sentinel通过(2)中INFO的回复可以得到要监控的主服务器的所有从服务器信息,然后对每个从服务器执行(1)~(2),也即和每个从服务器建立两个连接,一个订阅从服务器的__sentinel__:hello频道,一个用于发送和接收命令,然后每10秒向从服务器发送INFO命令;

(4)向主服务器和从服务器发送消息

Sentinel默认每2秒向主从服务器的__sentinel__:hello频道publish以下消息,其实也即是告知其它同样监控该主服务器的Sentinel自身的存在:

(5)接收主从服务器的__sentinel__:hello频道消息

根据(4),由于每个Sentinel都会发布消息,从而监控同一个主服务器的多个Sentinel会相互发现;

(6)创建连向其它Sentinel的命令连接

当Sentinel发现其它同样监控该主服务器的Sentinel后,会向这些Sentinel建立命令连接,同样这些Sentinel也会创建连向该Sentinel的命令连接,但这些Sentinel之间不会创建订阅连接;

(7)检测主观下线状态

  • 默认情况下,Sentinel每1秒向所有它所建立的命令连接(包括主从服务器,其他监控该主服务器的Sentinel)发送PING命令,并通过返回结果判断是否在线;
  • 返回结果分为有效回复(+PONG,-LOADING,-MASTERDOWN三种)和无效回复(除有效回复意外的回复,或者在指定时间内没有返回回复);
  • Sentinel配置文件中的down-after-milliseconds参数指定了Sentinel判断实例(实例包括主从服务器,其他监控该主服务器的Sentinel)进入主观下线所需的时间长度:如果一个实例在down-after-milliseconds毫秒内,连续向Sentinel返回无效回复,则Sentinel认为该实例已经进入主观下线状态;

(8)检查客观下线状态

Sentinel使用以下命令询问其他Sentinel是否同意主服务器已下线:

SENTINEL is-master-down-by-addr <master-ip> <port> <current_epoch> <runid> 

其它Sentinel收到该命令后,会检查主服务器是否已经下线,然后向该Sentinel回复以下内容:

1)<down_state>

2)<leader_runid>

3)<leader_epoch>

Sentinel统计同意主服务器下线的Sentinel数量n(包括自身在内),如果n>quorum(quorum在Sentinel配置文件中设置),则认为主服务器已客观下线;

(9)选举领头Sentinel

使用raft算法,在所有监控主服务器的Sentinel中选出一个领头(leader),由该领头进行下一步的故障转移;

具体过程:

  • 已经发现主服务器客观下线的Sentinel(源Sentinel)向其它所有监控主服务器的Sentinel发送SENTINEL is-master-down-by-addr命令(参考(8)),但此时run_id参数的值不再是*,而是自身的运行id,表示要求其它Sentinel选自己为领头;
  • 其它Sentinel可能会收到多个SENTINEL is-master-down-by-addr命令(因为有可能多个Sentinel认为主服务器客观下线),则使用先到先得原则:最先向目标Sentinel发送命令的源Sentinel被设为该目标Sentinel的领头,此后其它的Sentinel要求选他们为领头的请求则被拒绝(也即使用第一个Sentinel的运行ID和配置纪元作为SENTINEL is-master-down-by-addr命令的回复);
  • 如果某个Sentinel被半数以上的其他监控该主数据库的Sentinel设为领头,则该Sentinel成为领头;如果在给定的时间内没有选出领头,则各个Sentinel在随机一段时间后重新发起参选请求,进行下一轮的选举;

(10)故障转移

由领头Sentinel负责,首先在下线主服务器的从服务器中,选出一个执行slaveof no one命令,变为新的主服务器N,然后其他从服务器执行slaveof N_ip N_port,从而变为N的从服务器,而已下线的旧主服务器,现在也变为N的从服务器;

6、Redis集群(cluster)

基本概念:数据库分片的一种,即在服务器端进行分片,对Redis进行水平扩容(scale out);

注:而在客户端分片的做法就是由客户端决定每个键交由哪个数据库节点存储,下次从该数据库读取,具体应用为codis;

综述参考:Redis集群方案应该怎么做?

配置方法:

暂时可参考:Redis如何手动创建集群

7、redis守护进程启动:redis-server --daemonize yes

8.redis选择使用哪个数据库:

(1)command: select {db_num}

(2)redis-cli -n {db_num}

9.redis批量正则删除key

redis-cli KEYS "prefix:*" | xargs redis-cli DEL

相关参考:How to atomically delete keys matching a pattern using Redis

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值