Redis进阶(一)

通过简单的KV数据库理解Redis

Redis进阶(一)

分为访问模块,操作模块,索引模块,存储模块

底层数据结构

Redis进阶(一)

除了String类型,其他类型都是一个键对应一个集合,键值对的存储结构采用哈希表

Redis进阶(一)

哈希表由多个哈希桶组成,桶中存储entry元素,存储key和value的地址

但是当hash冲突元素过多会导致查询效率变慢,所以引入 rehash操作

采用两个全局hash表,但是从一个哈希表复制到另一个哈希表肯定会造成线程阻塞,所以使用 渐进式哈希:分摊到多次拷贝

接受第一次请求就拷贝第一个索引的entry元素,下一次再拷贝第二个,以此类推

对于集合类型的底层数据结构:双向链表,压缩列表,哈希表,跳表,整数数组

压缩列表:

Redis进阶(一)

跳表:

增加多级索引,通过索引位置的跳转,快速找到元素 (时间复杂度为logn)

不同操作所对应的时间复杂度也不同

对于单个元素的操作一般为O(1)

范围操作一般为O(n),一般使用scan来代替

统计操作,因为底层的数据结构中有元素个数的统计,所以时间复杂度为O(1)

为什么快

单线程(多路复用)不会阻塞在一个客户端的请求连接上,因为在请求过程中有可能会因为监听到有连接请求但是迟迟没有建立起连接或者建立起连接数据一直没有到达都会发生阻塞,所以采用多路复用非阻塞结构,允许在内核中存在多个监听套接字和已连接套接字,采用事件回调机制,当有事件到来,进入一个队列,redis处理队列中的请求,针对每个事件都有相应的 回调函数

在内存中操作数据

高效的底层数据结构

持久手段

AOF(记录操作命令,所以恢复时还要执行,速度慢)

mysql数据库是写前日志,redis是写后日志,所以不会阻塞当前的写操作

但是有两个风险:1.redis宕机,有丢失一段时间内数据的可能 2.因为在主线程中进行aof操作,有可能会阻塞下一个操作

但是随着时间的推移,aof文件越来越大怎么办,数据恢复效率肯定会降低?

引入aof重写

多变一,把多条对同一个键的旧操作合并成最新的一条操作

但是aof重写会阻塞主线程吗?

不会的,和aof追加写入不一样,采用的不是主线程,是由主线程fork出的子线程bgrewriteaof线程重写,子线程里也有父线程的内存的最新数据(共享页表)

在重写过程中,客户端的操作也会由主线程写入当前aof的缓冲区和重写aof的缓冲区,保证宕机也是数据齐全的,重写之后数据也是最新的

Redis进阶(一)

RDB(内存快照)

把某一时刻的状态记录到磁盘上

两个命令生成RDB:1. save,使用主线程,会阻塞主线程 2. bgsave,使用子线程,避免了阻塞问题( 但是主线程只可读,不可写

那么在记录到磁盘的时间段内,怎么保证数据不被修改?

使用bgsave+写时复制:主线程修改处于RDB中的数据时,需要生成一个副本,子进程把副本数据写进RDB文件

虽然RDB恢复速度快,但是进行持久化的时间间隔却不好把控,所以Redis4.0推出AOF和RDB结合的方法:在两次RDB持久化期间,期间发生的改动由AOF记录,这样恢复数据即快,又避免了频繁fork子线程对主线程的阻塞。

高可用

主从

主从同步过程

第一步:从库发送同步命令,包括主库ID和复制进度offset

第二步:主库生成RDB文件,发送RDB文件,全量复制,发送包含两个参数:主库ID和复制进度offset

第三步:主库把第二步过程中收到的命令发送到从库

那么当从库增多,主库fork子线程生产RDB的压力必然会增大,所以采用主-从-从架构,进行从库之间的级联,取一些从库帮主库分担压力

Redis进阶(一)

那么网络断了怎么办?

redis2.8之前是再进行一次全量复制

之后是进行增量复制

在redis中存在一个 环形缓冲区,记录主库写的进度和从库复制的进度,由两个参数确定,master-repl-offset和slave-repl-offset

网络断开再重连之后,从库根据offset位置进行增量复制就好

但是如果从库复制进度赶不上主库写的进度,缓冲区就会被覆盖,就会触发从库的全量复制,所以一般增大缓冲区为2倍

Original: https://www.cnblogs.com/zz01/p/16558850.html
Author: 山野村夫01
Title: Redis进阶(一)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621420/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 如何成为一名开发人员——第 3 部分:人际交往能力

    在前两节中,我介绍了技术和非技术技能。但是,编程生涯不能凭空出现!需要彼此才能茁壮成长。 你听说过”铁磨铁”这句话。这在软件开发行业当然是正确的。我的大部分…

    数据库 2023年6月14日
    083
  • 解读《Benchmarking Hybrid OLTP&OLAP Database Systems》| StoneDB学术分享会

    编者按: Benchmarking 作为一个衡量标尺,可从不同的维度来客观公正公平的评价相关产品,例如:对应数据测评而言,有 TPC-C、TPC-H,TP-DS 等等。现有的这些测…

    数据库 2023年6月11日
    0120
  • redis简述

    redis是什么? Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、…

    数据库 2023年6月14日
    079
  • 姜还是老的辣,看看老战哥的老底儿和老道

    上周日,2022年8月7日,参加了一场久违的半马。中伏天的傍晚,热度不减,全程挥汗如雨,虽不是PB,但也算尽力。晒一下战绩。 支付宝安全发这个通道要对接,今天上午10点,产品经理跟…

    数据库 2023年6月9日
    0142
  • 聊天软件的后端架构NIO

    聊天软件等的技术,朋友圈,钉钉,微博分两种技术模式:1.读扩散:也就是拉模式消息会存储到自己的发件箱里面,然后让每个上线的人去拉取未读消息,缺点是每次都要去好多底线去拉取数据,读操…

    数据库 2023年6月16日
    0145
  • select,poll,epoll

    select、poll、epoll 区别总结: 底层实现 select/poll 首先把关注的Socket集合从用户态拷贝到内核态,然后由内核检测事件,遍历整个集合(由于线性结构实…

    数据库 2023年6月16日
    095
  • OpenSSL的升级

    参考链接,复制过来的知乎一个博主的,可能知乎对链接做了些限制,导致不好复制,这里也正好再复习一遍:https://zhuanlan.zhihu.com/p/133999805?fr…

    数据库 2023年6月14日
    0104
  • day04-2发送文件

    多用户即时通讯系统04 4.编码实现03 4.6功能实现-发送文件功能实现 4.6.1思路分析 客户端(发送者): 先把文件a.jpg读取到客户端的字节数组 把文件对应的字节数组封…

    数据库 2023年6月11日
    086
  • 《Unix环境高级编程》笔记

    基础 Unix操作系统体系结构 操作系统就是一种软件,它管理控制计算机的硬件资源,提供程序运行的环境,这种软件又被称为内核(Kernel)。内核提供的接口被称为系统调用(Syste…

    数据库 2023年6月11日
    0110
  • ATM系统开发(Java版)

    ATM系统Java模拟开发总结 ATM系统开发 技术点分析 1.面向对象编程 每个用户的账户都是一个对象,所以需要设计账户类Accent用于创建账户对象封装账户信息。 2.使用集合…

    数据库 2023年6月16日
    074
  • python-django框架中使用FastDFS分布式文件系统

    一、安装FastDFS 1-1:执行docker命令安装 bash;gutter:true; 安装tracker docker run -dti –network=host –…

    数据库 2023年6月6日
    0103
  • navicat~导出数据库密码

    当我们mysql密码忘记了,而在navicat里有记录,我们应该如何导出这个密码呢? 第一步:文件菜单,导出链接,导出连接获取到 connections.ncx 文件 这里需要勾选…

    数据库 2023年5月24日
    0182
  • 一个诡异的MySQL查询超时问题,居然隐藏着存在了两年的BUG

    这一周线上碰到一个诡异的BUG。 线上有个定时任务,这个任务需要查询一个表几天范围内的一些数据做一些处理,每隔十分钟执行一次,直至成功。 通过日志发现,从凌晨5:26分开始到5:5…

    数据库 2023年6月16日
    0115
  • ShardingSphere 云上实践:开箱即用的 ShardingSphere-Proxy 集群

    本次 Apache ShardingSphere 5.1.2 版本更新为大家带来了三大全新功能,其中之一即为使用 ShardingSphere-Proxy chart 在云环境中快…

    数据库 2023年6月16日
    089
  • form表单内容序列化的两种方法

    form表单内容序列化 form表单自带两种方法serialize()方法和serializeArray()方法 1.serialize()方法 描&…

    数据库 2023年6月14日
    089
  • MySQL实战45讲 14

    14 | count(*)这么慢,我该怎么办? 在开发系统的时候,你可能经常需要 计算一个表的行数,比如一个交易系统的所有变更记录总数。 随着系统中记录数越来越多,select c…

    数据库 2023年6月16日
    0104
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球