Redis HyperLogLog底层实现和Redis 7.0特性主从复制优化

文章目录

  • Redis HyperLogLog和Redis 7.0
    • hyperloglog
      • 基本使用
      • 基本原理
    • Redis7新特性

Redis HyperLogLog和Redis 7.0

hyperloglog

基本使用

基数:在一个数据集合中不重复元素的个数

redis hyperloglog 是用来做基数统计的算法。它可以利用少量内存进行大量数据的统计。它是有误差的,误差在0.81%。

应用场景就比如:统计网页的UV (页面访问量 一个人访问一个网站多次但还是算一个人)。

# hyperloglog它只有三个命令:pfadd、pfcount、pfmerge
# 添加元素 可以添加1个 也可以添加多个
127.0.0.1:6379> pfadd mykey a b c d e f g h i j k 
(integer) 1
# 查询这个集合的基数
127.0.0.1:6379> pfcount mykey
(integer) 11

# 再创建一个集合
127.0.0.1:6379> pfadd mykey2 i j k l m n o p
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 8

# 还可以把两个集合合并成一个新集合
127.0.0.1:6379> pfmerge mykey3 mykey mykey2
OK
127.0.0.1:6379> pfcount mykey3
(integer) 16



基本原理

HyperLogLog基于概率论中伯努利试验并结合了极大似然估算方法,并做了分桶优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9bETsA5J-1680006850723)(picture/Redis/9922)]

Hyperloglog底层采用的是调和平均数,不是采用的算术平均数。

采用平均数的方式就是: (1000 + 30000) / 2 = 15500

采用调和平均数的方式就是: 2/(1/1000 + 1/30000) ≈ 1935.484

可见调和平均数比平均数的好处就是不容易受到大的数值的影响,比平均数的效果是要更好的。

hyperloglog在redis启动时是占12KB内存大小,随着时间推移可能会有一点点的变化,redis会把这12KB的内存分为16384个桶(桶其实就是比较长的bit数组),也就是2^14次方,

hyperloglog首先会将要存的值进行hash运算转换为64位的二进制比特串,取低14位,就得到当前值应该放进哪个桶中。剩余的50位的数据就决定往桶中放入什么内容,从第14位开始往前数,找到第一个为1的比特位数,比如17位是1,那么就是从第14位开始往前数第3位是1,然后把这个3转换为二进制数存入桶中,相当于就是存了一个K。

各个桶中会求出自己的Kmax值,然后根据所有通的估计值求出调和平均数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ugX4uwni-1680006850723)(picture/Redis/9923)]



Redis7新特性

提升了主从复制是性能

redis7版本以前主从复制是有两种:全量复制、增量复制。

当master节点执行一条更新命令时,它处理本机执行之外,还会往从库复制缓冲区(复制给从库)、复制积压区进行保存(将执行的命令做一个备份,slave断开连接重连时会用到)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q4BbWypW-1680006850724)(picture/Redis/image-20230328193950775.png)]

这种方式的问题是:

  • 会为每一个slave节点都创建一个从库复制缓冲区,那么仅仅为了主从复制这个功能就会消耗master节点比较大的内存空间,从库越多消耗的内存也越多
  • 在全量备份时会生成一个rdb文件,然后发送到从库复制缓冲区中再发送给salve1节点,如果这个时候再来一个slave节点,生成一个rdb文件是比较耗时的,Redis底层是让这些slave节点共用的同一份rdb文件,redis会把一个从库负责缓冲区中的内容拷贝到另一个从库负责缓存区,但这个容量可能几百MB或者个GB,那么就可能造成毫秒甚至是秒级单位中Redis无法响应客户端的请求,去做复制的事情去了
  • 我们可以在运行时设置复制积压缓冲区的大小,这样就会造成重新分配一块新的内存空间,然后将原来的数据拷贝到新的内存块中。

redis7版本就提出来共享从库复制缓冲区的优化点。将原来一整大块内存拆分为了很多小块内存(Block),使用链表的结构将多个block连接起来,每个block中还维护了一个变量refcount用来表示从库引用计数,各个从库的复制缓冲区都是读取的一块内存,只是移动指针表示各个从库读取到了哪一个位置。这样也就不存在了多个从库复制缓冲区进行数据复制的问题了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-35HD2wMa-1680006850724)(picture/Redis/image-20230328195838348.png)]

因为使用了链表,假如链表上的节点非常多,如果想要获取其中一个block,那么遍历起来会非常耗时,底层用来rax树的数据结构来优化,它和Trie树的区别是进行了压缩,如下所示是一个Trie数的结构,一个字母就是一个节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fldkW2cq-1680006850724)(picture/Redis/image-20230328201933629.png)]

而rax数如果此时某一个节点不会再分叉了,那么就把多个字母放在一个节点中,rax树其实就是压缩后的trie树。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uIxhuNOC-1680006850724)(picture/Redis/image-20230328202054482.png)]

在Rax树中它其实不是按照一个字母来存放的,而是按照bit位来存放的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/5312.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TC275-点亮属于AutoSAR的灯之MCAL配置

前面 前段时间算是通过S32K144这个芯片对AutoSAR开发的大概流程有了一个了解,但苦于最后代码集成和编译器配置上的烦恼,所以决定换一个平台来进行开发(有教程,手动狗头)。 英飞凌的Aurix系列——TC275。 配置 Reso…

【机器学习】线性回归

文章目录前言一、单变量线性回归1.导入必要的库2.读取数据3.绘制散点图4.划分数据5.定义模型函数6.定义损失函数7.求权重向量w7.1 梯度下降函数7.2 最小二乘法8.训练模型9.绘制预测曲线10.试试正则化11.绘制预测曲线12.试试sklearn库二、多变量线性回归1.导入库2.读取数据3.划分…

【C语言督学训练营 第五天】数组字符串相关知识

文章目录前言一、数组的定义1.一维数组①.如何定义②.声明规则③.内存分布④.初始化方法2.二维数组3.高维数组二、访问数组元素相关问题1.访问越界2.数组的传递三、Scanf与字符数组1.字符数组初始化2.scanf读取字符四、字符数组相关函数前言 今天的C语言训练营没有安排高维数组…

Ceres 自动求导解析-从原理到实践

Ceres 自动求导解析-从原理到实践 文章目录Ceres 自动求导解析-从原理到实践1.0 前言2.0 Ceres求导简介3.0 Ceres 自动求导原理3.1 官方解释3.2 自我理解4.0 实践4.1 Jet 的实现4.2 多项式函数自动求导4.3 BA 问题中的自动求导Reference1.0 前言 Ceres 有一个自动求导功能&…

信号集操作函数

控制原理:内核通过读取未决信号集来判断信号是否应被处理。信号屏蔽字mask可以影响未决信号集。而我们可以在应用程序中自定义set来改变mask。已达到屏蔽指定信号的目的。 更多函数具体使用 man *** 的方式查看手册 信号集操作函数使用原理分析https://www.bilibil…

Matbox V1.0.7更新预览与手册

哔哩哔哩地址 : Click Me! Github地址 : Click Me! YouTube演示地址 :Click Me! 快速更新命令 pip install https://github.com/PythonnotJava/MTBOX/releases/download/matbo1.0.7/matbox-1.0.7-py3-none-any.whl --upgradePyPi 链接 :…

TryHackMe-harder(boot2root)

harder 结合真实的渗透测试结果。该机器的灵感完全来自现实世界的渗透测试结果。也许你会认为它们非常具有挑战性,但没有任何兔子洞。一旦你有一个 shell,知道使用哪个底层 Linux 发行版以及某些配置的位置是非常重要的。 端口扫描 循例 nmap Web枚举 …

ShaderGraph前言

学习思路 线性代数要学习,也可以通过sg辅助学习线性代数。数据/公式图形化可视化观察记忆可以利用Preview Node和ZGrapher曲线工具。降维理解,3维降2维2维降1维参数多改多看多思考复杂运算常量化,遇到复杂运算过程可以尝试设定常量&#xff…

大屏使用dv-digital-flop定时刷新显示总人数

本文在基础上进行改进,后端使用若依后端IofTV-Screen: 🔥一个基于 vue、datav、Echart 框架的物联网可视化(大屏展示)模板,提供数据动态刷新渲染、屏幕适应、数据滚动配置,内部图表自由替换、Mixins注入等功…

一文实战 | RISC-V Linux入口地址2M预留内存优化

上篇分析了RISC-V Linux启动之页表创建,提到RISC-V Linux入口地址必须2M对齐,今天讲讲如何解决2M对齐的问题,或者说如何优化部分内存。 注意:本文基于linux5.10.111内核 内存占用分析 每颗芯片在出厂时,其bootrom就已…

二值mask转polygon/RLE (coco segment格式)

coco数据集annotation的segmentation并不是二值mask,而是polygon格式, 看一个annotation. {"segmentation": [[510.66,423.01,511.72,420.03,510.45......]], #两两组成(x,y)坐标,polygon格式"area": 702.1057499999998…

Leetcode: 236.二叉树的最近公共祖先

文章目录Leetcode:236.二叉树的公共祖先题目描述示例思路分析代码实现Leetcode:236.二叉树的公共祖先 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖…

医用超声检查设备

1.探头 线阵探头 孔径大,近场视野宽,分辨率好,旁瓣影响小 线阵探头的中心频率一般是7MHZ以上,探测深度比较浅,通常检查肌骨、血管、乳腺、动脉等表浅器官及组织等部位,所以也叫“浅表探头”。 凸阵探头 凸…

无线耳机哪个品牌好?四大国内蓝牙耳机品牌排行

现今,蓝牙耳机越来越成为人们外出必备的数码产品之一。随着蓝牙耳机品牌的增多,多种多样的蓝牙耳机出现在大众视野,而国产蓝牙耳机凭借更高的性价比而受到不少用户的欢迎。接下来,我来给大家推荐四款国产的蓝牙耳机,一…

软件工程导论(四)总体设计(临时)

模块耦合及其分类 A:定义 耦合:是对一个软件结构内不同模块间互连程序的度量。耦合强度取决于模块接口的复杂程度、通过接口的数据等。耦合度越高,模块独立性越弱 B:分类 耦合度从低到高 数据耦合标记耦合控制耦合公共耦合内容…

49天精通Java,第21天,Java内部类,看看文心一言、ChatGPT怎么说

目录文心一言谈Java内部类ChatGPT谈Java内部类下面来聊聊哪吒的见解。一、为什么需要内部类?二、内部类分为四种三、成员内部类1、什么是成员内部类2、代码实例3、成员内部类进阶代码实例4、控制台显示5、外部类访问内部类四、局部内部类五、匿名内部类1、匿名内部类…

TypeScript学习笔记一

文章目录一、类型注解二、TypeScript常用类型2.1 原始类型2.2 数组类型2.3 联合类型2.4 类型别名2.5 给函数添加类型2.6 对象类型2.7 对象的可选属性2.8 接口2.9 interface和type的对比2.10 接口继承2.11 元组2.12 类型推断2.13 类型断言2.14 字面量类型2.15 枚举2.16 any类型2…

OSPF(开放式最短路径优先协议2)

OSPF的不规则区域 远离骨干的非骨干区域 不连续骨干 使用tunnel隧道 在R2和R3之间构建一条隧道,之后,将这个隧道宣告到Area0,相当于将R3这个非法的ABR设备合法 化。 使用vpn隧道解决不规则区域的问题 可能产生选路不佳可能造成重复更新因为…

写毕业论文经验贴

首先说一句不要靠近word,会变得不幸。最好用latex写,不过我当时懒得下载latex了,于是后期改格式花了点时间 写论文之前 事先把所有的论文都查好并且整理好,论文第一、二章写起来就会很快; 把实验做顺溜,实…

设计模式-设计原则

设计原则 1.依赖倒置 高层不应该依赖低层,两者应该都依赖于抽象 抽象不应该依赖具体实现,具体应该依赖于抽象 自动驾驶系统公司是高层,汽车生产商是底层,自动驾驶系统不应该依赖于各种车型系统底层进行实现,因为这是…
最新文章