Redis 高可靠主线 - 主从复制
我们总说的 Redis 具有高可靠性,其实有两层含义: 一是数据尽量少丢失 二是服务尽量少中断 AOF 和 RDB 保证了前者,而对于后者,Redis 的做法就是增加副本冗余量,将一份数据同时保存在多个实例上。即使有一个实例出现了故障,需要过一段时间才能恢复,其他实例也可以对外提供服务,不会影响业务使用。 多实例保存同一份数据,听起来好像很不错,但是,我们必须要考虑一个问题:这么多副本,它们之间的数据如何保持一致呢?数据读写操作可以发给所有的实例吗? 实际上,Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。读操作:主库、从库都可以接收;写操作:首先到主库执行,然后,主库将写操作同步给从库。 那么,主从库同步是如何完成的呢?主库数据是一次性传给从库,还是分批同步?要是主从库间的网络断连了,数据还能保持一致吗?本节我们就聊聊主从库同步的原理,以及应对网络断连风险的方案。 一、主从库间是如何同步的?当我们启动多个 Redis 实例的时候,它们相互之间就可以通过 replicaof 命令形成主库和从库的关系: 当然也可以直接在配置文件中配置: ...
Redis 高性能主线 - 持久化
目前,Redis 的持久化主要有两大机制,即 AOF(Append Only File)日志和 RDB 快照。 一、 AOF说到日志,我们比较熟悉的是数据库的写前日志(Write Ahead Log, WAL)(redolog,binlog等),也就是说,在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。不过,AOF 日志正好相反,它是写后日志,“写后”的意思是 Redis 是先执行命令,把数据写入内存,然后才记录日志。 那 AOF 为什么要先执行命令再记日志呢?要回答这个问题,我们要先知道 AOF 里记录了什么内容。 传统数据库的日志,例如 redo log(重做日志),记录的是修改后的数据,而 AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本形式保存的。 我们以 Redis 收到“set testkey testvalue”命令后记录的日志为例,看看 AOF 日志的内容。其中,“*3”表示当前命令有三个部分,每部分都是由“$+数字”开头,后面紧跟着具体的命令、键或值。这里,“数字”表示这部分中的命令、键或值一共有多少字节。例如,“$3 set...
深究 URL encode
一、一段陈年老代码在读一份陈年老代码时,发现了下面这段有意思的东西,这段代码的目的,是将 web 请求的入参 url encode 之后,计算 md5 当做签名。 123456789101112import java.net.URLEncoder;encodedFix(URLEncoder.encode(value, "UTF-8"))private static String encodedFix(String encoded) { encoded = encoded.replace("+", "%20"); encoded = encoded.replace("*", "%2A"); encoded = encoded.replace("%7E", "~"); return encoded;} 那么问题就来了,url encode 就 encode 呗,为什么还要再 encodedFix 修复...
Redis 高性能主线 – 线程模型&网络框架
在看这篇文章之前,需要先对 linux 的 epoll 模型有所了解。请参考: Linux IO 模型 IO 多路复用 Redis内置了一个高性能事件循环器,叫做AE。其定义和实现可以在ae*.h/cpp这些文件中找到。 事件驱动模型Redis 的事件驱动模型处理 2 类事件: 文件事件,如连接建立、接受请求命令、发送响应等; 时间事件,如 Redis 中定期要执行的统计、key 淘汰、缓冲数据写出、rehash等。 一、文件事件处理Redis 的文件事件采用典型的 Reactor 模式进行处理。Redis 文件事件处理机制分为 4 部分: 连接 socket IO 多路复用程序 文件事件分派器 事件处理器 虽然多个文件事件可能会并发出现,但 IO 多路复用程序总会将所有产生事件的 socket 放入一个队列中,通过这个队列,有序的把这些文件事件通知给文件分派器。 1. IO多路复用Redis 封装了 4 种多路复用程序,每种封装实现都提供了相同的 API 实现。编译时,会按照性能和系统平台,选择最佳的 IO 多路复用函数作为底层实现,选择顺序是,首先尝...
Redis 高性能主线
三大主线 高性能主线:包括线程模型、数据结构、持久化、网络框架; 高可靠主线:包括主从复制、哨兵机制; 高可扩展主线;包括数据分片、负载均衡。 今天,我们来探讨一个很多人都很关心的问题:“为什么单线程的 Redis 能那么快?”首先,我要和你厘清一个事实,我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的 一方面,Redis 的大部分操作在内存上完成,再加上它采用了高效的数据结构,例如哈希表和跳表,这是它实现高性能的一个重要原因。 另一方面,就是 Redis 采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率 Redis单线程处理IO请求性能瓶颈主要包括2个方面: 1、任意一个请求在server中一旦发生耗时,都会影响整个server的性能,也就是说后面的请求都要等前面这个耗时请求处理完成,自己才能被处理到。耗时的操作包括以下几种: a、操作bigk...
IO
Linux 五种IO模型一、概念说明:1. 用户空间和内核空间现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。 2. 进程切换为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。 从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化: 保存处理机上下文,包括程序计数器和其他寄存器。 更新 PCB(Proce...
IO Multiplexing
在 Linux 系统之中有一个核心武器:epoll 池,在高并发的,高吞吐的 IO 系统中常常见到 epoll 的身影。 IO 多路复用后台的程序只需要 1 个线程就可以管理多个 fd 句柄,来应对所有的业务方的 IO 请求。这种一对多的 IO 模式我们就叫做 IO 多路复用。 多路是指?多个业务方(句柄)并发下来的 IO 。 复用是指?复用这一个后台线程。 站在 IO 系统设计人员的角度,业务方要创建多个 fd,你就需要负责这些 fd 的处理,并且最好还要并发起来。 业务方没法限制,那么只能后台 loop 程序了,并且要 loop 的非常之快!要让每一个 fd 觉得,你只在给他一个人干活。 最朴实的实现方式?如果不用任何其他系统调用,能否实现 IO 多路复用? 答案是可以的。 我们写个 for 循环,每次都尝试 IO 一下,读/写到了就处理,读/写不到就 sleep。这样我们不就实现了 1 对多的 IO 多路复用嘛。 12345while True: for each 句柄数组 { read/write(fd, /* 参数 */...
Redis 高性能主线 - 数据结构
高性能主线:包括线程模型、数据结构、持久化、网络框架; 高可靠主线:包括主从复制、哨兵机制; 高可扩展主线;包括数据分片、负载均衡。 一、键和值以什么结构组织?为了实现从键到值的快速访问,Redis 使用了一个哈希表来保存所有键值对。 当我们往哈希表中写入更多数据时,哈希冲突是不可避免的问题。Redis 解决哈希冲突的方式,就是链式哈希。 但是,这里依然存在一个问题,哈希冲突链上的元素只能通过指针逐一查找再操作。随着哈希表里写入的数据越来越多,哈希冲突可能也会越来越多,这就会导致某些哈希冲突链过长,进而导致这个链上的元素查找耗时长,效率下降。因此,redis 引入了 rehash 机制,来对哈希表进行扩容。 1. rehashrehash 的主要思路是增加现有的哈希桶数量,让逐渐增多的 entry 元素能在更多的桶之间分散保存,减少单个桶中的元素数量(缩短链表的长度),从而减少单个桶中的冲突。 具体到 Redis, 它默认使用了两个全局哈希表:哈希表1和哈希表2。一开始,当你刚插入数据时,默认使用哈希表1,此时的哈希表2并没有被分配空间。随着数据逐步增多,Redis 开始执...
Redis 详解
被公司要求做一次技术分享,刚好很忙随手选了个缓存方面的题目。忙(拖)了N久之后,终于有闲心搞一搞了,顺便当总结八股文了,说不定以后还用得到。 这一个系列的笔记会持续的比较久,从极客时间上的《Redis 核心技术与实战》课程入手,计划着碰到什么啃什么吧,就当拓展知识面了,毕竟对于单身狗来说,别的啥没有,就是时间多。 三大主线 高性能主线:包括线程模型、数据结构、持久化、网络框架; 高可靠主线:包括主从复制、哨兵机制; 高可扩展主线;包括数据分片、负载均衡。 Redis 问题画像图
云卷云舒
众鸟高飞尽,孤云独去闲。 相看两不厌,只有敬亭山。 [{"url":"https://img.mofish.zone/wp-content/uploads/2021/11/20211107232530897-scaled.jpg","alt":"","title":""},{"url":"https://img.mofish.zone/wp-content/uploads/2021/11/20211107232541727-scaled.jpg","alt":"","title":""},{"url":"https://img.mofish.zone/wp-content/uploads/2021/11/20211107232550308-scaled.jpg","alt":"","title":""},{"url":"https://img.mofish.zone/wp-content/uploads/2021/11/20211107232558593-scaled.jpg","alt":"","title":""},{"url":"https://img.mofis...