Redis中3种特殊的数据类型(BitMap、Geo和HyperLogLog)
作者:Sun_翁航 发布时间:2024-01-24 11:20:47
前言
Reids 在 Web 应用的开发中使用非常广泛,几乎所有的后端技术都会有涉及到 Redis 的使用。Redis 种除了常见的字符串 String、字典 Hash、列表 List、集合 Set、有序集合 SortedSet 等等之外,还有一些不常用的数据类型,这里着重介绍三个。下面话不多说了,来一起看看详细的介绍吧。
BitMap
BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态, 其中的 key 就是对应元素本身,实际上底层也是通过对字符串的操作来实现。Redis 从 2.2 版本之后新增了setbit, getbit, bitcount 等几个 bitmap 相关命令。虽然是新命令,但是本身都是对字符串的操作,我们先来看看语法:
SETBIT key offset value
其中 offset 必须是数字,value 只能是 0 或者 1,咋一看感觉没啥用处,我们先来看看 bitmap 的具体表示,当我们使用命令 setbit key (0,2,5,9,12) 1后,它的具体表示为:
byte | bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
---|---|---|---|---|---|---|---|---|
byte0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
byte1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |
可以看出 bit 的默认值是 0,那么 BitMap 在实际开发的运用呢?这里举一个例子:储存用户在线状态。这里只需要一个 key,然后把用户 ID 作为 offset,如果在线就设置为 1,不在线就设置为 0。实例代码:
//设置在线状态
$redis->setBit('online', $uid, 1);
//设置离线状态
$redis->setBit('online', $uid, 0);
//获取状态
$isOnline = $redis->getBit('online', $uid);
//获取在线人数
$isOnline = $redis->bitCount('online');
Geo
Redis 的 GEO 特性在 Redis 3.2 版本中推出, 这个功能可以将用户给定的地理位置信息储存起来, 并对这些信息进行操作。GEO 的数据结构总共有六个命令:geoadd、geopos、geodist、georadius、georadiusbymember、gethash,这里着重讲解几个。
1.GEOADD
GEOADD key longitude latitude member [longitude latitude member ...]
将给定的空间元素(纬度、经度、名字)添加到指定的键里面。 这些数据会以有序集合的形式被储存在键里面, 从而使得像 GEORADIUS 和 GEORADIUSBYMEMBER 这样的命令可以在之后通过位置查询取得这些元素。例子:
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
2.GEOPOS
GEOPOS key member [member ...]
从键里面返回所有给定位置元素的位置(经度和纬度),例子:
redis> GEOPOS Sicily Palermo Catania NonExisting
1) 1) "13.361389338970184"
2) "38.115556395496299"
3.GEODIST
GEODIST key member1 member2 [unit]
返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。指定单位的参数 unit 必须是以下单位的其中一个:(默认为m)
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
redis> GEODIST Sicily Palermo Catania
"166274.15156960039"
4.GEORADIUS
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。距离单位和上面的一致,其中后面的选项:
WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。距离的单位和用户给定的范围单位保持一致。
WITHCOORD: 将位置元素的经度和维度也一并返回。
WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。这个选项主要用于底层应用或者调试, 实际中的作用并不大。
redis> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
2) "190.4424"
2) 1) "Catania"
2) "56.4413"
HyperLogLog
Redis 的基数统计,这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数、页面实时UV)、在线用户数等。但是它也有局限性,就是只能统计数量,而没办法去知道具体的内容是什么。
当然用集合也可以解决这个问题。但是一个大型的网站,每天 IP 比如有 100 万,粗算一个 IP 消耗 15 字节,那么 100 万个 IP 就是 15M。而 HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值,不管存储的内容是什么,它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值。
这个数据结构的命令有三个:PFADD、PFCOUNT、PFMERGE
1.PFADD
redis> PFADD databases "Redis" "MongoDB" "MySQL"
(integer) 1
redis> PFADD databases "Redis" # Redis 已经存在,不必对估计数量进行更新
(integer) 0
2.PFCOUNT
redis> PFCOUNT databases
(integer) 3
3.PFMERGE
PFMERGE destkey sourcekey [sourcekey ...]
将多个 HyperLogLog 合并为一个 HyperLogLog, 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合的并集。合并得出的 HyperLogLog 会被储存在 destkey 键里面, 如果该键并不存在,那么命令在执行之前, 会先为该键创建一个空的 HyperLogLog 。
redis> PFADD nosql "Redis" "MongoDB" "Memcached"
(integer) 1
redis> PFADD RDBMS "MySQL" "MSSQL" "PostgreSQL"
(integer) 1
redis> PFMERGE databases nosql RDBMS
OK
redis> PFCOUNT databases
(integer) 6
来源:https://juejin.im/post/5aa72131518825556a7211af
猜你喜欢
- 抛出问题:求一数组如 l = [0, 1, 2, 3, -4, 5, -6],求该数组的最大连续子数组的和 如结果为[0,1,2,3,-4,
- time 模块主要包含各种提供日期、时间功能的类和函数。该模块既提供了把日期、时间格式化为字符串的功能,也提供了从字符串恢复日期、时间的功能
- 本文实例讲述了正则表达式验证IPV4地址功能。分享给大家供大家参考,具体如下:IPV4地址由4个组数字组成,每组数字之间以.分隔,每组数字的
- enumerate函数用于遍历序列中的元素以及它们的下标。enumerate函数说明:enumerate()是python的内置函数enum
- python中使用input()函数来获取用户输入函数 input() 让程序暂停运行,等待用户输入一些文本,获取用户的输入后,Python
- 前言最近在维护项目的python项目代码,项目使用了 python 的日志模块 logging, 设定了保存的日志数目, 不过没有生效,还要
- 目的: 找出路径坐在的所有python文件(.py结尾),返回列表。代码:def list_py(path = None): if path
- 受杰森的《Almost Looks Like Work》启发,我来展示一些病毒传播模型。需要注意的是这个模型并不反映现实情况,因此不要误以为
- 有些接口参数是一个文件格式,比如fiddler 抓包参数如下显示这个接口的 form-data fiddler 显示的和不带文件参数的接口有
- 前言大家都看过彩带飘落吧?这个在比较喜庆的场合是很常见的:还有“跑马灯”效果,听起来很陌生,其实很常见,下面的就是:来源:https://w
- 定义总是很抽象。存储进程其实就是能完成一定操作的一组SQL语句,只不过这组语句是放在数据库中的(这里我们只谈SQL SERVER)。如果我们
- python标准库OS模块简介os就是“operating system”的缩写,顾名思义,os模块提供的就是各种 Python 程序与操作
- 在对浏览器兼容性要求越来越高的时候,大家是否正在寻找一个完整的解决方案呢?继《[原]最新CSS兼容方案》之后,更新的CSS hack出炉啦,
- 本文实例讲述了Python Django中间件,中间件函数,全局异常处理操作。分享给大家供大家参考,具体如下:应用名/middleware.
- Pandas函数的核心功能是,既计算了统计值,又保留了明细数据。为了更好地理解transform和agg的不同,下面从实际的应用场景出发进行
- 本文实例为大家分享了python利用tkinter实现屏保的具体代码,供大家参考,具体内容如下import randomimport tki
- boto操作import datetimeimport boto.s3.connectionfrom boto.s3.key import
- 什么是Matplotlib?Matplotlib是Python中的一个库,用于创建静态和动态动画,并使用其内置函数绘制。它有很多内置特性和内
- 一、实验目的熟练掌握pandas中的groupby操作二、实验原理groupby(by=None, axis=0, level=None,
- 在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子。一般用