[Redis#9] stream | geospatial | HyperLogLog | bitmaps | bitfields

server/2024/12/5 3:00:48/

目录

1.Streams

事件驱动机制

事件

JS (做界面)

事件是干什么的?

2.geospatial

3.HyperLogLog

4.bitmaps

5.bitfields


redis 常用的 data types 有 10 种,我们前面已经讲到了 5 种,这篇文章将对剩下的 5 种特殊数据结构进行讲解~

1.Streams

  • 应用场景主要用为队列(阻塞队列)

事件驱动机制

事件
  • epoll / io 多路复用
  • 每次网卡/socket上有可读可写的数据都会通过这种事件回调机制来通知到咱们的应用程序代码。
JS (做界面)
  • 点击事件、键盘事件、窗口大小改变/位置改变事件...
事件是干什么的?
  • 有些操作,我们也不知道它啥时候出现,只能等这个 事件 出现了之后,再采取动作
消防员的角度
  • 一旦着火,立即使用干粉灭火器~~
  • 如果没着火,只能等着~~
此处的“着火”就是“事件”
  • “使用干粉灭火器”就是“事件触发的回调函数”

官方文档的意思,就是stream类型

  • 就可以用来模拟实现这种事件传播的机制~~
  • stream就是一个队列 (阻塞队列)
  • 属于是 List blpop / brpop升级版本。

2.geospatial

Introduction to the Redis Geospatial data type

  • 用来 存储坐标 (经纬度)
  • 存储一些点之后,就可以让用户给定一个坐标,去从刚才存储的点里进行查找。(按照半径、矩形区域...)
  • 这个功能在“地图”应用中非常重要~~

理解:


3.HyperLogLog

Introduction to the Redis HyperLogLog data type

  • 应用场景只有一个:估算集合中的元素个数。

场景分析:

  • Set,有一个应用场景,统计服务器的UV(用户访问的次数)。
    • 使用Set当然可以统计UV,但是最大的问题在于,如果UV数据量非常大,Set就会消耗很多的内存空间。
  • 假设Set存储userid,每个userid按照8个字节算:
    • 1亿UV => 8亿字节 => 0.8G => 800MB
  • HyperLogLog可以最多使用12KB空间,实现上述效果:
    • HyperLogLog不存储元素的内容,但是能够记录元素的特征,从而在新增元素的时候,能够知道当前新增的元素是一个已经存在的元素,还是一个崭新的第一次出现的元素。
    • 这个东西具体还是得分析源码~~ 核心思路“位操作” => 精确性~~(存在一定的误差)
  • 用来计数(记录出当前集合中有多少个不同的元素)
    • 但是不能告诉你这些元素都是啥~~
    • The Redis HyperLogLog implementation uses up to 12 KB and provides a standard error of 0.81%。
  • 对于实现的理解:
    • 分析源码
    • 数学方式来进行计算~~

4.bitmaps

Introduction to Redis bitmaps

  • 使用 bit 位来表示整数。
    • 把 10 存储到位图中
    • 0000 0000 0000 000
    • 计算机进行位运算,一般都是比较高效的~~
  • 位图本质上,就还是一个集合,属于是 Set 类型针对整数的特化版本~~
    • bitmap 类型存储元素了!!
    • 节省空间
  • HyperLogLog
    • 更省空间呀!!
    • hyperloglog 存储元素的时候,提取特征的过程是不可逆的!! (信息量丢失了)
    • 给你个猪肉,能把它做成火腿肠
    • 给你个火腿肠,能还原回猪肉嘛~
  • bitmap 节省空间,也存在一定的可逆性

内存占用(结合使用场景选择:

  • hyperloglog<bit<set

5.bitfields

  • 理解:就是C中说到的位段,这里称为位域
  • C 进阶,自定义数据类型 => 结构体在内存中的布局。
    • 位域本质上是让我们精确进行位操作的一种方法~~
    • 上述 Redis 中的 bitfield 和 C 中的位域,非常相似的!!
    • bitfield 可以理解成一串二进制序列 (字节数组)
    • 同时可以把这个字节数组中的 某几个位,赋予特定的含义,并且可以进行 读取/修改/算术运算 相关操作~~
    • 位域这个东西,相比于之前的 String / hash 来说,目的仍然是节省空间

示例

  • struct Test {
    • int a:8;
    • int b:16;
    • int c:8;
    • }
    • 此处的数字,就描述这个成员实际占几个 bit 位!!
    • 位域本质上是让我们精确进行位操作的一种方法~~

感兴趣的 uu 可以读一下这篇文章

https://redditinc.com/blog/how-we-built-rplace

摘录:

为了解决竞争条件问题,可以引入分布式锁来确保同一时间只有一个用户能够执行图块放置操作。此外,可以使用 Redis 的 BITFIELD 命令来实现更细粒度的控制和优化数据存储。下面是结合了这些改进后的绘制图块步骤:

  • 获取分布式:在开始处理用户的请求之前,首先尝试获取一个分布式锁(例如使用 Redis 的 SETNX 命令)。如果无法获取锁,则拒绝该请求,并返回错误信息给用户。
  • 读取并检查冷却时间:从 Cassandra 中读取用户上次放置图块的时间戳。如果时间戳显示用户还没有度过冷却期(5分钟),则释放锁,并向用户返回错误。
  • 写入磁贴详细信息
    • 使用 Redis 的 BITFIELD 命令来更新位图,标记新的图块位置。
    • 将磁贴详细信息写入 Redis 和 Cassandra。这一步骤中,你可以利用 Redis 的原子性来确保操作的完整性。
  • 更新用户最后放置时间:将当前时间戳作为用户最后一次放置图块的时间写入 Cassandra。
  • 通知 WebSocket 服务:指示 WebSocket 服务发送消息到所有连接的客户端,告知他们新图块的信息。
  • 释放分布式:完成所有操作后,释放分布式锁,允许其他请求继续处理。

通过这种方式,我们可以确保在同一时间内只有一个用户可以成功地放置图块,从而避免了竞争条件。同时,使用 Redis 的 BITFIELD 可以高效地管理图块的状态,因为它是基于位的操作,非常适合表示二进制状态的数据,如图块是否被占据等。

另外,为了进一步提高系统的健壮性,还可以考虑实施更严格的速率限制策略,比如使用 Redis 的 INCREVAL 脚本来实现滑动窗口算法,以防止用户或机器人频繁地进行图块放置请求。


结构体的内存对齐 回顾:

结构体对齐规则

1. 结构体的第一个成员放在结构体变量在内存中存储位置的0偏移量开始

2. 从第2个成员往后的所有成员,都放在一个对齐数(成员的大小和默认对齐数的较小值)的整数的整数倍的地址处

  • VS中对齐数的默认值为8

3. 结构体的总大小是结构体的所有成员的对齐数中最大的那个对齐数的整数倍

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

为什么存在内存对齐?

平台原因(移植原因):

  • 不是所有的硬件平台都能访问任意地址上的任意数据的
    • 某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常

性能原因

  • 数据结构(尤其是栈)应该尽可能地在自然边界上对齐
    • 原因:为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问
  • 总的来说,结构体的内存对齐是拿空间来换取时间的做法

设计结构体时,如何既满足对齐,又要节省空间?

  • 合理安排结构体顺序让占用空间小的成员尽量集中在一起

(感兴趣的 uu 可以看一下博主的这篇前文19.(C进阶)结构体(全),上面是截取的部分内容


《魔兽世界》(World of Warcraft,简称WoW)和《Dota 2》是两款非常受欢迎的多人在线游戏


http://www.ppmy.cn/server/147449.html

相关文章

【鸿蒙开发】第二十三章 Network 网络服务

目录​​​​​​​ 1 简介 1.1 约束与限制 2 HTTP数据请求 2.1 request 接口开发步骤 2.2 requestInStream接口开发步骤 3 WebSocket连接 3.1 开发步骤 4 Socket 连接 4.1 Socket 连接主要场景 4.1.1 TCP/UDP Socket进行数据传输 4.1.2 TCP Socket Server 进行数…

NLP 的研究任务

自然语言处理&#xff08;Natural Language Processing, NLP&#xff09; NLP 的研究任务 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;1. **机器翻译**2. **情感分析**3. **智能问答**4. **文摘生成**5. **文本分类**6. **舆论分析**7. **知识图谱*…

23种设计模式之适配器模式

目录 1. 简介1.1 定义1.2 结构和组成部分 2. 代码2.1 MediaPlayer2.2 AdvanceMediaPlayer2.3 VicPlayer2.4 Mp4Player2.5 MediaPlayerAdapter2.6 AudioPlayer2.7 Test 3. 适用场景4. 优点和缺点5. 总结 1. 简介 1.1 定义 适配器模式&#xff08;Adapter Pattern&#xff09;是…

android视频播放器之DKVideoPlayer

一个老牌子的播放器了&#xff0c;项目可能已经有些日子没有维护了。但是使用效果还是不错的。支持多种视频格式&#xff0c;及重力感应、调节亮度等多种效果。想来想去&#xff0c;还是记录下来&#xff0c;我会在文章的最后注明github地址&#xff1a; 首先引入依赖&#xff…

【Elasticsearch】06-JavaRestClient查询

1. MatchAll查询与结果解析 public class ElasticQueryTest {private RestHighLevelClient client;BeforeEachpublic void init() {client new RestHighLevelClient(RestClient.builder(HttpHost.create("http://nuaamvp.cn:9200")));}AfterEachvoid tearDown() {i…

威胁驱动的网络安全方法论

摘要 目前的网络安全风险管理实践很大程度上是由合规性要求驱动的&#xff0c;这使得公司/组织不得不在安全控制和漏洞上投入人力/物力。&#xff08;风险管理涉及多个方面&#xff0c;包括资产、威胁、漏洞和控制&#xff0c;并根据事故发生的可能性及造成的影响进行评估。威…

2024年11月一区SCI-Alpha evolution-附Matlab免费代码

引言 本期介绍了一种新的进化算法——阿尔法进化算法Alpha evolution&#xff0c;AE。它使用带有自适应基向量和随机和自适应步长的alpha算子更新解。该算法于2024年11月最新发表在JCR 1区&#xff0c;中科院2区SCI期刊Engineering Applications of Artificial Intelligence。…

数据库视图应用指南:案例详解与分析

目录 一、定义与特点二、类型与分类三、创建与使用1. 创建视图2. 查看视图3. 修改视图4. 删除视图5. 查询视图四、示例案例一. 综合简单示例案例二:简化复杂查询案例三:数据安全与访问控制案例四:数据整合与报表生成案例五:数据抽象与业务逻辑封装五、应用场景与优势数据库…