Redis入门指南---读书笔记

第一章 简介

Redis的全称是remote dictionary server(远程字典服务器)

Redis的优势:
1. 存储形式与在应用程序中存储方式相近
2. 提供对不同数据类型的方便操作(交集)
3. 因此与MySQL数据库相比,使用起来性能更高更方便。

Redis是内存存储,但是可以通过异步方式写入硬盘,支持持久化。

第二章 准备
  1. 启动rRedis
    直接运行(redis-server),也可以初始化脚本启动,使得redis随系统自动运行(配置redis的运行方式,持久化文件,日志文件的存储位置等)。

  2. 停止redis(redis-cli SHUTDOWN):断开所有客户端连接,持久化后退出。将redis的进程kill,与SHUWDOWN一样。

  3. redis没有整数类型

  4. 可以将redis中的每个字典理解成一个独立的数据库(数据库的命名默认从0开始,默认支持16个数据库)。

  5. redis不支持为每个数据库设立独立的密码,多个数据库之间不是完全隔离的。数据库因此更像一种命名空间。不同的应用应该使用不同的redis实例。

第三章 入门
  1. 所有Redis命令都是原子操作。

  2. Redis不支持数据类型嵌套

  3. Redis中每个键都属于一个明确的数据类型,通过HSET建立的键是散列类型,通过SET命令建立的键是字符串类型。

  4. 列表类型内部使用的是双向链表,获取越接近两端的数据越快。

  5. 集合类型在Redis内部使用的是值为空的散列表实现的。

  6. 有序集合类型使用散列表和跳跃表实现的。

  7. Redis包含的数据类型有字符串,散列类型,列表类型,集合类型,有序集合类型。

第四章 进阶
  1. Redis提供了对事务的支持。当一个事务中出现错误时,如果是语法错误的话所有命令都不会执行,如果是运行出错(比如用散列类型的命令操作集合类型的键)的话,其他没错的命令都会执行,包括出错命令之后的命令。Redis不提供回滚功能。

  2. Redis事务的执行使用的是MULTI EXEC命令。事务之间的命令是一起执行的,没办法提前获得GET命令的值再对其加一后SET,所以可以使用WATCH命令监控键,如果在监控键的后面下一个事务的前面有客户端修改了该键的值,那么下一个事务就不会执行。用户需要自己重新执行。

  3. 过期时间

  4. 排序

  5. 任务队列

    1. 生产者消费者模型,可以用Redis的列表实现。BRPOP命令可以阻塞到列表中有元素为止。(即一有新任务就通知消费者,不用消费者去循环访问)
    2. 优先级队列:发送确认邮件要比发送通知邮件优先级高,所以用两个列表存储。一旦高优先级的任务队列有任务,不管低优先级的任务有多少个,高优先级的优先执行。
  6. 发布/订阅模式

    1. 执行SUBSCRIBE命令后客户端就会进入订阅状态,不可以使用非发布/订阅的命令。
    2. 使用PSUBSCRIBE可以重复订阅一个频道。
  7. 客户端和Redis使用TCP协议连接。在执行多个命令时每条命令都需要等待上一条命令执行完。可以通过管道一次传输发送多条命令并在执行完成后一次返回。

  8. 节省空间

第七章 持久化
  1. 缓存穿透:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

  2. 缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

  3. Redis的两种持久化方式:RDB(定时将数据写到硬盘上)和AOF(每次将命令记下)。

  4. RDB方式是通过快照完成的。使用fork函数创建一个子进程,子进程负责写入硬盘,父进程继续处理请求。使用的是copy-on-write策略,如果父进程要修改数据,那么就会复制一份,保证子进程最后存储的是执行fork指令那一刻的内存数据。新的快照结束后才会删除掉旧的快照。

  5. AOF方式:每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。每当达到一定条件时,Redis就会自动重写优化AOF文件。启动时会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,速度比RDB慢。实际上,操作系统默认是将数据写入硬盘缓冲中,每30秒同步一次,我们需要手动修改同步的时间间隔。

  6. Redis允许同时开启AOF和RDB。

第八章 集群
  1. 复制:主数据库和从数据库(主数据库的修改会自动同步到从数据库),直接修改从数据库的数据会出现错误。

  2. 复制原理:当一个从数据库启动后会发送SYNC命令给主数据库,主数据库会保存快照并将保存期间收到的命令缓存,然后全部发给从数据库。之后每次主数据库有写命令时都会同步给从数据库。断线重连能够支持有条件的增量数据传输(断线期间执行的命令传送给从数据库)。

  3. 乐观复制:允许在一定时间内主从数据库的内容是不一样的。

  4. 从数据库也可以作为其他数据库的主数据库。构成一个图结构。

  5. 因为持久化操作比较耗时,所以可以通过复制功能建立一个从数据库,从数据库使用持久化,主数据库禁用持久化。从数据库崩溃后主数据库自动将数据同步过来就好。主数据库崩溃则将从数据库变为主数据库,再让原来的主数据库变为从数据库(不可以直接启动主数据库,否则会将从数据库也清空)

  6. 无硬盘复制:使用硬盘复制会生成RDB快照(即使主数据库禁用了持久化),这样子下次启动后主数据库会以该快照恢复数据,而复制发生的时间点是不确定的。硬盘复制受到硬盘性能影响。所以,Redis引入了无硬盘复制,直接将快照通过网络发送给从数据库。

  7. 增量复制:从数据库存储主数据库ID,主数据库维护一个积压队列存储发送给从数据库的命令,同时记下偏移量。从数据库也记录接收到的命令偏移量。每次主从连接准备就绪后,主数据库先检查ID(确保是和自己同步过的从数据库),然后检查偏移量。不满足条件的话就执行全部同步。

  8. 哨兵工具监控Redis系统的运行情况,实现自动化的系统监控和故障恢复功能。可以使用多个哨兵保证系统足够稳健,哨兵也会互相监控。它的功能有如下两个:

    1. 监控主从数据库是否正常运行
    2. 主数据库出现故障自动将从数据库转化为主数据库。
  9. 哨兵工作原理:

    1. 启动后会与要监控的主数据库建立两条连接。一条订阅该主数据库的__sentinel__:hello频道,获得其他监控该数据库的哨兵节点的信息。一个定期向主数据库发送INFO等命令来获取主数据库本身的信息。

    2. 连接完成后哨兵定时执行下述操作:

      1. 每10s发送INFO命令给主从数据库
      2. 每2s发送自己的信息给主从数据库的 __sentinel__:hello频道
      3. 每1s给主从数据库,其他哨兵节点发送PING命令
    3. 当一个哨兵PING的节点未回复时则认为它主观下线,如果有指定数量的哨兵认为它下线了那么该节点就是客观下线。如果该节点是主数据库,那么选举领头哨兵(Raft算法)进行故障恢复(选一个当主数据库(优先级越高,偏移量越大的,ID越小的),其他都变成该主数据库的从数据库,包括原来的主数据库)。

  10. 哨兵的部署: 尤其是当进行客户端分片时使用多个哨兵节点监控多个主数据库会因为Redis不支持连接复用而产生大量连接。(客户端分片:由客户端决定哪个键应该放在哪个数据库)

  11. 客户端分片:启动多个Redis数据库节点,由客户端决定每个键交由哪个数据库节点存储,下次客户端读取该键时直接到该节点读取。扩容很麻烦。可以使用预分片技术。扩容的时候只需要将某些Redis实例分配到新的服务器上就好。(预分片技术:事先预想到之后的规模,扩容之后只需要将某些键进行迁移到新的机器)

  12. 集群拥有和单机实例一样的性能,支持故障恢复。对于涉及多键的命令,如果不在同一个节点则不能支持,限制了只能用0号数据库。

  13. 惊群:惊群现象(thundering herd)就是当多个进程和线程在同时阻塞等待同一个事件时,如果这个事件发生,会唤醒所有的进程,但最终只可能有一个进程/线程对该事件进行处理,其他进程/线程会在失败后重新休眠,这种性能浪费就是惊群。Nginx中使用mutex互斥锁解决这个问题,具体措施有使用全局互斥锁,每个子进程在epoll_wait()之前先去申请锁,申请到则继续处理,获取不到则等待,并设置了一个负载均衡的算法(当某一个子进程的任务量达到总设置量的7/8时,则不会再尝试去申请锁)来均衡各个进程的任务量。

  14. 集群中节点的增加:要将新节点A加入B所在的集群。客户端发送命令给A,A收到后根据命令中指定的IP地址和端口(也就是B)发起握手,B将A认为当前集群中的一员。握手成功后,B会使用gossip协议将A的信息通知给集群中的每一个节点。

  15. 在Redis中,所有的键会分配给16384个插槽。当插槽要从一个节点移动到另一个节点,要解决插槽中键的临时丢失问题。(P189页五个步骤)

  16. 客户端向集群中任何一个节点发送命令后,如果在当前节点则返回,否则返回一个MOVE重定向请求,客户端再向正确节点发起一个连接。(客户端缓存插槽的路由信息)

  17. 集群的故障恢复类似于哨兵。如果一个主数据库下线而没有从数据库,那么整个集群默认会进入下线状态无法继续工作。

  18. 当不需要数据分片或者已经在客户端进行分片的场景下哨兵就足够使用了,但如果需要进行水平扩容,则集群是一个非常好的选择。

补充
19. Redis一般不使用持久化,因为持久化会影响性能。当使用主从模式时,可以让从数据库持久化
20. Redis也很少使用集群,因为Redis的集群功能当需要扩容时需要运维手动移动插槽,同时对Redis客户端的要求也比较高,无法做到对客户端透明。以及集群实现的代码耦合比较严重,出问题难以修复
21.Redis也没有对主从IP封装成统一接口给客户端,需要客户端自己填对应的IP,因此单独用Redis的主从也不太友好 。
codis

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值