当前位置: 首页 > news >正文

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 的性能和扩展性进一步提升,适用于更多复杂的应用场景。

相关文章:

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

1. HyperLogLog 简介 HyperLogLog 是一种用于基数估计的概率数据结构。它并不是一种新的数据结构,而是 Redis 中的一种字符串类型。HyperLogLog 的主要优点是能够利用极少的内存空间完成对独立总数的统计,适用于统计大量数据的独立元素数量&#xff0c…...

MyBatis(30)如何在 MyBatis 中使用 XML 和注解混合配置方式

在MyBatis中,你可以灵活地选择XML配置方式、注解方式,或者将这两种方式混合使用来配置你的映射器(Mapper)。使用混合配置方式,你可以结合两者的优势,例如,利用XML配置复杂查询和动态SQL&#xf…...

强化学习与控制模型结合例子

强化学习与模型控制结合 强化学习(Reinforcement Learning, RL)与控制模型结合,可以通过整合传统控制理论和现代RL算法,利用控制模型提供的动态信息和稳定性保障,同时利用RL的学习能力优化控制策略。这种结合的方式被称为模型辅助强化学习(Model-Assisted Reinforcement…...

RKNN3588——利用推理YOLOv8推理图片

1. yolov8_test.py import os import cv2 import numpy as np from class_type import CLASSES# 设置对象置信度阈值和非极大值抑制(NMS)阈值。 OBJ_THRESH 0.25 NMS_THRESH 0.45 IMG_SIZE (640, 640)def filter_boxes(boxes, box_confidences, box_…...

【ARMv8/v9 GIC 系列 1.7 -- GIC PPI | SPI | SGI | LPI 中断使能配置介绍】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC 各种中断使能配置PPIs(每个处理器私有中断)SPIs(共享外设中断)SGIs(软件生成的中断)LPIs(局部中断)GIC 各种中断使能配置 在ARM GICv3和GICv4架构中,不同类型的中断(如PPIs、SPIs、SGIs和LPIs)可以通过不同的方式进…...

uniapp开发射击类小游戏

使用 UniApp 开发射击类小游戏可以遵循以下步骤: 项目规划 确定游戏的主题、玩法、关卡设计等。规划游戏的界面布局,包括游戏主界面、游戏场景、得分显示等。 技术准备 熟悉 UniApp 的开发文档和相关 API。准备所需的开发工具,如 HBuilderX。…...

spring6框架解析(by尚硅谷)

文章目录 spring61. 一些基本的概念、优势2. 入门案例实现maven聚合工程创建步骤分析实现过程 3. IoC(Inversion of Control)基于xml的bean环境搭建获取bean获取接口创建实现类依赖注入 setter注入 和 构造器注入原生方式的setter注入原生方式的构造器注…...

Open3D 计算点云的马氏距离

目录 一、概述 1.1原理 1.2应用 二、代码实现 三、实现效果 3.1原始点云 3.2计算后点云 一、概述 1.1原理 马氏距离(Mahalanobis Distance)是一种度量多维数据点与数据分布中心之间距离的方法。与欧几里得距离不同,马氏距离考虑了数据…...

Java事务(Transaction)

Java事务(Transaction)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列组成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务的引入主要是为了解决并发操作数据…...

算法 —— 二分查找

目录 二分查找 在排序数组中查找元素的第一个和最后一个位置 搜索插入位置 x的平方根 山峰数组的峰顶索引 寻找峰值 搜索旋转排序数组中的最⼩值 点名 二分查找模板分为三种:1、朴素的二分模板 2、查找左边界的二分模板 3、查找右边界的二分模板&#xf…...

Mysql explain语句详解与实例展示

首先简单介绍sql: SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。 1. 数据查询语言DQL 数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句…...

Python基础问题汇总

为什么学习Python? 易学易用:Python语法简洁清晰,易于学习。广泛的应用领域:适用于Web开发、数据科学、人工智能、自动化脚本等多种场景。强大的库支持:拥有丰富的第三方库,如NumPy、Pandas、TensorFlow等…...

【讲解下iOS语言基础】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...

【网络安全】实验一(网络拓扑环境的搭建)

一、本次实验的实验目的 学习利用 VMware 创建虚拟环境 学习利用 VMware 搭建各自网络拓扑环境 二、创建虚拟机 三、克隆虚拟机 选择克隆的系统必须处于关机状态。 方法一: 方法二: 需要修改克隆计算机的名字,避免产生冲突。 四、按照要求完…...

Docker-基础

一,Docker简介,功能特性与应用场景 1.1 Docker简介 Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器…...

《昇思25天学习打卡营第14天|onereal》

第14天学习内容如下: Diffusion扩散模型 本文基于Hugging Face:The Annotated Diffusion Model一文翻译迁移而来,同时参考了由浅入深了解Diffusion Model一文。 本教程在Jupyter Notebook上成功运行。如您下载本文档为Python文件&#xff0c…...

LeetCode 744, 49, 207

目录 744. 寻找比目标字母大的最小字母题目链接标签思路代码 49. 字母异位词分组题目链接标签思路代码 207. 课程表题目链接标签思路代码 744. 寻找比目标字母大的最小字母 题目链接 744. 寻找比目标字母大的最小字母 标签 数组 二分查找 思路 本题比 基础二分查找 难的一…...

【AI资讯】可以媲美GPT-SoVITS的低显存开源文本转语音模型Fish Speech

Fish Speech是一款由fishaudio开发的全新文本转语音工具,支持中英日三种语言,语音处理接近人类水平,使用Flash-Attn算法处理大规模数据,提供高效、准确、稳定的TTS体验。 Fish Audio...

微服务数据流的协同:Eureka与Spring Cloud Data Flow集成指南

微服务数据流的协同:Eureka与Spring Cloud Data Flow集成指南 在构建基于Spring Cloud的微服务架构时,服务发现和数据流处理是两个关键的组成部分。Eureka作为服务发现工具,而Spring Cloud Data Flow提供了数据流处理的能力。本文将详细介绍…...

java生成json格式文件(包含缩进等格式)

生成json文件的同时保留原json格式&#xff0c;拥有良好的格式&#xff08;如缩进等&#xff09;&#xff0c;提供友善阅读支持。 pom.xml依赖增加&#xff1a; <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactI…...

Python面试题:如何在 Python 中读取和写入 JSON 文件?

在 Python 中读取和写入 JSON 文件可以使用 json 模块。以下是具体的示例&#xff0c;展示了如何读取和写入 JSON 文件。 读取 JSON 文件 要读取 JSON 文件&#xff0c;可以使用 json.load() 方法。下面是一个示例代码&#xff1a; import json# 假设有一个名为 data.json 的…...

FlutterWeb渲染模式及提速

背景 在使用Flutter Web开发的网站过程中&#xff0c;常常会遇到不同浏览器之间的兼容性问题。例如&#xff0c;在Google浏览器中动画和交互都非常流畅&#xff0c;但在360浏览器中却会出现卡顿现象&#xff1b;在Google浏览器中动态设置图标颜色正常显示&#xff0c;而在Safa…...

群体优化算法----化学反应优化算法介绍,解决蛋白质-配体对接问题示例

介绍 化学反应优化算法&#xff08;Chemical Reaction Optimization, CRO&#xff09;是一种新兴的基于自然现象的元启发式算法&#xff0c;受化学反应过程中分子碰撞和反应机制的启发而设计。CRO算法模拟了分子在化学反应过程中通过能量转换和分子间相互作用来寻找稳定结构的…...

Go语言如何入门,有哪些书推荐?

Go 语言之所以如此受欢迎&#xff0c;其编译器功不可没。Go 语言的发展也得益于其编译速度够快。 对开发者来说&#xff0c;更快的编译速度意味着更短的反馈周期。大型的 Go 应用程序总是能在几秒钟之 内完成编译。而当使用 go run编译和执行小型的 Go 应用程序时&#xff0c;其…...

【密码学】密码学体系

密码学体系是信息安全领域的基石&#xff0c;它主要分为两大类&#xff1a;对称密码体制和非对称密码体制。 一、对称密码体制&#xff08;Symmetric Cryptography&#xff09; 在对称密码体制中&#xff0c;加密和解密使用相同的密钥。这意味着发送方和接收方都必须事先拥有这…...

Bean的管理

1.主动获取Bean spring项目在需要时&#xff0c;会自动从IOC容器中获取需要的Bean 我们也可以自己主动的得到Bean对象 &#xff08;1&#xff09;获取bean对象&#xff0c;首先获取SpringIOC对象 private ApplicationContext applicationContext //IOC容器对象 (2 )方法…...

Unity 数据持久化【PlayerPrefs】

1、数据持久化 文章目录 1、数据持久化PlayerPrefs基本方法1、PlayerPrefs概念2、存储相关3、读取相关4、删除数据思考 信息的存储和读取 PlayerPrefs存储位置1、PlayerPrefs存储的数据在哪个位置2、PlayerPrefs 数据唯一性思考 排行榜功能 2、Playerprefs实践1、必备知识点-反…...

linux-虚拟内存-虚拟cpu

1、进程&#xff1a; 计算机中的程序关于某数据集合上的一次运行活动。 狭义定义&#xff1a;进程是正在运行的程序的实例&#xff08;an instance of a computer program that is being executed&#xff09;。广义定义&#xff1a;进程是一个具有一定独立功能的程序关于某个…...

某某市信息科技学业水平测试软件打开加载失败逆向分析(笔记)

引言&#xff1a;笔者在工作过程中&#xff0c;用户上报某某市信息科技学业水平测试软件在云电脑上打开初始化的情况下出现了加载和绑定机器失败的问题。一般情况下&#xff0c;在实体机上用户进行登录后&#xff0c;用户的账号信息跟主机的机器码进行绑定然后保存到配置文件&a…...

vue3+antd 实现点击按钮弹出对话框

格式1&#xff1a;确认对话框 按钮&#xff1a; 点击按钮之后&#xff1a; 完整代码&#xff1a; <template><div><a-button click"showConfirm">Confirm</a-button></div> </template> <script setup> import {Mod…...