9、Redis 高级数据结构 HyperLogLog 和事务

1. HyperLogLog

简介

HyperLogLog 是一种用于基数估计的概率数据结构。它并不是一种新的数据结构,而是 Redis 中的一种字符串类型。HyperLogLog 的主要优点是能够利用极少的内存空间完成对独立总数的统计,适用于统计大量数据的独立元素数量,例如统计网站的 UV(Unique Visitor)。

使用场景

假设你需要开发一个统计网站每天 UV 的模块。统计 PV(Page View)非常简单,每个网页一个独立的 Redis 计数器即可。但统计 UV 则需要去重,同一个用户一天内多次访问只计数一次。这就要求每个网页请求都要带上用户的 ID。

一种简单的方案是为每个页面一个独立的 set 集合来存储所有当天访问过此页面的用户 ID。当一个请求过来时,使用 SADD 命令将用户 ID 塞进去,通过 SCARD 命令取出集合的大小即可获得 UV 数据。然而,如果页面访问量非常大,这种方案会非常浪费内存。

HyperLogLog 的优点

HyperLogLog 提供了不精确的去重计数方案,虽然不精确但误差极小(0.81%)。这种精确度已经足以满足 UV 统计需求。例如,通过 HyperLogLog,可以用 12KB 的内存统计多达 2^64 个数据。

操作命令

  1. PFADD

    PFADD key element [element ...]
    

    向 HyperLogLog 添加元素。例如:

    PFADD 08-15:u:id "u1" "u2" "u3" "u4"
    
  2. PFCOUNT

    PFCOUNT key [key ...]
    

    计算一个或多个 HyperLogLog 的独立总数。例如:

    PFCOUNT 08-15:u:id
    
  3. PFMERGE

    PFMERGE destkey sourcekey [sourcekey ...]
    

    求出多个 HyperLogLog 的并集并赋值给 destkey。

原理概述

HyperLogLog 基于概率论中的伯努利试验,结合了极大似然估算方法,并做了分桶优化。具体来说,HyperLogLog 通过分桶、估算、调和平均数等方法实现了高效的基数估计。

  1. 数学原理

    通过 hash 函数将数据转为比特串,从而模拟抛硬币实验。比特串中的 0 和 1 分别代表硬币的反面和正面,通过统计出现正面的位置来估算实验次数。

  2. 结合实例理解实现原理

    通过 hash 函数,将用户 ID 转化为比特串,前 14 位用来分桶,剩下的比特位记录首次出现 1 的位置。每个桶中记录 k_max 值,然后通过调和平均数计算总体估算值。

  3. Redis 中的 HyperLogLog 实现

    Redis 的 HyperLogLog 实现中,采用 16384 个桶,每个桶 6 位,内存占用 12KB。具体实现中,value 被 hash 成 64 位,前 14 位用于分桶,剩下 50 位记录首次出现 1 的位置。通过多次估算并求平均值,可以得出较为精确的统计结果。

2. Redis 事务

简介

Redis 提供了简单的事务功能,允许将一组命令作为一个整体执行,要么全部执行,要么全部不执行。这对于需要原子性操作的场景非常重要。

事务的基本命令

  1. MULTI

    开始事务。例如:

    MULTI
    
  2. EXEC

    提交事务,执行事务中的所有命令。例如:

    EXEC
    
  3. DISCARD

    取消事务,丢弃事务中的所有命令。例如:

    DISCARD
    

事务中的命令错误处理

  1. 命令错误

    如果事务中的命令有语法错误(如将 SET 写成 SETT),整个事务不会执行。

  2. 运行时错误

    如果事务中的命令有运行时错误(如将 SADD 写成 ZADD),事务会执行正确的部分,错误部分会返回错误,但不会回滚已经执行的命令。

WATCH 命令

为了确保事务中的 key 没有被其他客户端修改,可以使用 WATCH 命令。WATCH 命令会监视指定的 key,如果在事务执行之前 key 被修改,事务将不会执行。例如:

WATCH key
MULTI
SET key value
EXEC

如果在 MULTI 和 EXEC 之间,其他客户端修改了 key,则 EXEC 将不会执行,返回 nil

Pipeline 和事务的区别

  1. Pipeline

    Pipeline 是客户端的行为,通过将多个命令一起发送,减少网络延迟。服务器无法区分命令是否通过 pipeline 发送,因此无法保证命令的原子性。

  2. 事务

    事务是在服务器端实现的,通过 MULTI 和 EXEC 命令保证一组命令的原子性执行。事务中的命令会被服务器缓存,直到 EXEC 命令执行时,才依次执行缓存的命令。

结合使用

可以将事务和 pipeline 结合使用,减少事务命令在网络上的传输时间,提高 Redis 处理查询请求的能力。

3. Redis 7.0 前瞻

Redis 7.0 引入了多个性能优化和新功能,包括降低写入时复制内存的开销、提升内存效率、改进 fsync 避免大量磁盘写入、优化延迟表现、Redis 函数、细粒度权限、改进子命令处理和 Lua 脚本等。

Redis 主从复制原理

  1. 全量同步

    主库通过 fork 子进程生成内存快照,将数据序列化为 RDB 格式同步到从库。

  2. 命令传播

    主从完成全量同步后,主库将变更数据的命令发送到从库,使从库数据与主库保持一致。

Redis 复制缓存区相关问题分析

  1. 多从库时主库内存占用过多

    主库为每个从库分配独立的复制缓冲区,导致内存占用过多。

  2. OutputBuffer 拷贝和释放的堵塞问题

    OutputBuffer 数据量大时,拷贝和释放操作可能造成堵塞,影响性能。

  3. ReplicationBacklog 的限制

    ReplicationBacklog 是实现部分重同步的基础,但其大小限制和拷贝问题需要解决。

Redis 7.0 共享复制缓存区的设计与实现

Redis 7.0 引入共享复制缓存区方案,通过将复制数据放在全局的缓冲区中,多个从库共享这份数据,减少内存占用。

  1. ReplicationBuffer 的裁剪和释放

    Redis 通过减少引用计数来裁剪和释放 ReplicationBuffer。具体来说,当从库使用完某个数据块时,减少其引用计数,引用计数为 0 时释放数据块。

  2. 数据结构的选择

    Redis 7.0 使用 rax 树实现 replBufBlock 的索引,提高查询效率。rax 树占用内存少,查询效率高,适用于大规模数据的索引和查询。

4. 总结

HyperLogLog 和事务是 Redis 中两个重要的高级功能。HyperLogLog 提供了高效的基数估计算法,适用于大数据场景的去重统计。Redis 事务提供了简单的原子性操作,适用于需要保证数据一致性的场景。通过 Redis 7.0 的优化和新功能,Redis 的性能和扩展性进一步提升,适用于更多复杂的应用场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习第四十六周周报 FMP

文章目录 week46 FMP摘要Abstract1. 题目2. Abstract3. FMP3.1 优化框架3.2 优化器 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程 5. 结论6.代码复现1. FMP2. fairGNN小结参考文献 week46 FMP 摘要 本周阅读了题为Chasing Fairness in Graphs: A GNN Architecture Per…

Mac OS系统中Beyond Compare 4破解方式

文章出处 https://blog.csdn.net/qq_42418042/article/details/137544113 前言 记录实操过程,以防以后找不到了~ 实际原理是启动时删除文件,实现无限试用 实操过程 下载安装包 官网链接 https://www.scootersoftware.com/download.php 解压、移动到应…

【Spring Cloud】微服务的简单搭建

文章目录 🍃前言🎄开发环境安装🌳服务拆分的原则🚩单一职责原则🚩服务自治🚩单向依赖 🍀搭建案例介绍🌴数据准备🎋工程搭建🚩构建父子工程🎈创建父…

leetcode每日一题-3033. 修改矩阵

题目描述: 解题思路:简单题目,思路非常直接。对列进行遍历,记录下最大值,然后再遍历一遍,把-1替换为最大值。需要注意的是进行列遍历和行遍历是不同的。 官方题解: class Solution { public:v…

行业事故---语雀

文章目录 时间线剖析心得 时间线 根据公告中关于故障的时间点梳理如下: 14:07 数据存储运维团队收到监控系统报警,定位到原因是存储在升级中因新的运维工具 bug 导致节点机器下线;14:15 联系硬件团队尝试将下线机器重新上线;15:…

网络漏洞挖掘实测报告

关于作者:个人主页 网络漏洞挖掘实测报告 一、前言 网络漏洞挖掘是信息安全领域中至关重要的一环。通过挖掘和修复漏洞,可以有效地保护系统免受潜在的攻击和破坏。本报告旨在记录一次完整的网络漏洞挖掘实测过程,包括实施方法、过程、结果以…

微软正在放弃React

最近,微软Edge团队撰写了一篇文章,介绍了微软团队如何努力提升Edge浏览器的性能。但在文中,微软对React提出了批评,并宣布他们将不再在Edge浏览器的开发中使用React。 我将详细解析他们的整篇文章内容,探讨这一决定对…

笔记:SpringBoot+Vue全栈开发2

笔记:SpringBootVue全栈开发2 1. MVVM模式2. Vue组件化开发3. 第三方组件element-ui的使用4. axios网络请求5. 前端路由VueRouter 1. MVVM模式 MVVM是Model-View-ViewModel的缩写,是一种基于前端开发的架构模式,其核心是提供对View和ViewMod…

Leetcode 77:组合

给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 未剪枝版&#xff1a; public List<List<Integer>> combine(int n, int k) {backtracking(n,k,1);System.out.println(res);return res;}public void backtracking(int n,int k,int …

【全面介绍下如何使用Zoom视频会议软件!】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

如何使用Python脚本实现SSH登录

调试IDE&#xff1a;PyCharm Python库&#xff1a;Paramiko 首先安装Paramiko包到PyCharm&#xff0c;具体步骤为&#xff1a;在打开的PyCharm工具中&#xff0c;选择顶部菜单栏中“File”下的“Settings”&#xff0c;在设置对话框中&#xff0c;选择“Project”下的“Proje…

线程安全的原因及解决方法

什么是线程安全问题 线程安全问题指的是在多线程编程环境中&#xff0c;由于多个线程共享数据或资源&#xff0c;并且这些线程对共享数据或资源的访问和操作没有正确地同步&#xff0c;导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现&#xff0c;通常是…

视频提取字幕怎么弄?5个快速获取视频字幕的方法

在忙碌而又充满活力的生活中&#xff0c;我们常常在通勤路上和午休间隙通过视频来获取信息和放松心情。 但有时候&#xff0c;我们想把视频里那些令人难忘的瞬间或关键信息保存下来&#xff0c;方便以后回顾或者分享。然而&#xff0c;手动摘录不仅费时&#xff0c;还容易漏掉…

【网络安全】实验七(ISA防火墙的规则设置)

一、实验目的 二、配置环境 打开两台虚拟机&#xff0c;并参照下图&#xff0c;搭建网络拓扑环境&#xff0c;要求两台虚拟机的IP地址要按照图中的标识进行设置&#xff0c;并根据搭建完成情况&#xff0c;勾选对应选项。注&#xff1a;此处的学号本人学号的最后两位数字&…

VRay渲染有什么技巧?渲染100邀请码1a12

渲染是视觉行业非常重要的一环&#xff0c;没有渲染就没有效果图&#xff0c;常用的渲染器有Vray&#xff0c;而Vray渲染有很多技巧&#xff0c;可以让渲染更快更省&#xff0c;下面我们总结下。 1、删除无用对象 检查场景&#xff0c;看是否有一些不需要渲染的物体和灯光&am…

时间处理的未来:Java 8全新日期与时间API完全解析

文章目录 一、改进背景二、本地日期时间三、时区日期时间四、格式化 一、改进背景 Java 8针对时间处理进行了全面的改进&#xff0c;重新设计了所有日期时间、日历及时区相关的 API。并把它们都统一放置在 java.time 包和子包下。 Java5的不足之处&#xff1a; 非线程安全&…

代码的坏味道——长参数

前言&#xff1a;一个函数的参数越少越好&#xff0c;并不是参数少或不传更优雅&#xff0c;而是有其他方案来优化长参数。一个函数的参数尽量不要超过3个&#xff0c;如果超过了这个限制&#xff0c;那么代码的坏味道就产生了。 一、整合参数 如果参数很多&#xff0c;那么第…

VueQuill 富文本编辑器技术文档快速上手

VueQuill 富文本编辑器技术文档 1. 安装 VueQuill2. 配置 VueQuill3. 在组件中使用 VueQuill4. 配置选项5. 事件处理6. 数据格式7. 自定义工具栏8. 示例项目结构9. 常见问题如何添加图片上传功能&#xff1f;如何自定义编辑器主题&#xff1f; 在此之前&#xff0c;我讲解过关于…

十一、作业

1.从大到小输出 写代码将三个整数数按从大到小输出。 void Swap(int* px, int* py) {int tmp *px;*px *py;*py tmp;} int main() {int a 0;int b 0;int c 0;scanf("%d %d %d", &a, &b, &c);int n 0;if (a<b){Swap(&a, &b);}if (a &l…

移动校园(2):express构建服务器,小程序调用接口,展示数据

express做服务器框架&#xff0c;mssql连接数据库&#xff0c;uni-request调用接口 这是文件夹目录 然后是index.js内容 const expressrequire(express) const appexpress() const uniRouterrequire("./uniRouter") const config{user:sa,password:123456,server:l…