前言

Reids 在 Web 应用的开发中使用非常广泛,几乎所有的后端技术都会有涉及到 Redis 的使用。Redis 种除了常见的字符串 String、字典 Hash、列表 List、集合 Set、有序集合 SortedSet 等等之外,还有一些不常用的数据类型,这里着重介绍三个。下面话不多说了,来一起看看详细的介绍吧。

BitMap

BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态, 其中的 key 就是对应元素本身,实际上底层也是通过对字符串的操作来实现。Redis 从 2.2 版本之后新增了setbit, getbit, bitcount 等几个 bitmap 相关命令。虽然是新命令,但是本身都是对字符串的操作,我们先来看看语法:

1
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。实例代码:

1
2
3
4
5
6
7
8
9
10
11
//设置在线状态
$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

1
GEOADD key longitude latitude member [longitude latitude member ...]

将给定的空间元素(纬度、经度、名字)添加到指定的键里面。 这些数据会以有序集合的形式被储存在键里面, 从而使得像 GEORADIUS 和 GEORADIUSBYMEMBER 这样的命令可以在之后通过位置查询取得这些元素。例子:

1
2
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

2.GEOPOS

1
GEOPOS key member [member ...]

从键里面返回所有给定位置元素的位置(经度和纬度),例子:

1
2
3
redis> GEOPOS Sicily Palermo Catania NonExisting
1) 1) "13.361389338970184"
 2) "38.115556395496299"

3.GEODIST

1
GEODIST key member1 member2 [unit]

返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。指定单位的参数 unit 必须是以下单位的其中一个:(默认为m)

m   表示单位为米。
km  表示单位为千米。
mi  表示单位为英里。
ft  表示单位为英尺。

1
2
redis> GEODIST Sicily Palermo Catania
"166274.15156960039"

4.GEORADIUS

1
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。距离单位和上面的一致,其中后面的选项:

WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。距离的单位和用户给定的范围单位保持一致。
WITHCOORD: 将位置元素的经度和维度也一并返回。
WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。这个选项主要用于底层应用或者调试, 实际中的作用并不大。

1
2
3
4
5
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

1
2
3
4
5
redis> PFADD databases "Redis" "MongoDB" "MySQL"
(integer) 1
 
redis> PFADD databases "Redis"  # Redis 已经存在,不必对估计数量进行更新
(integer) 0

2.PFCOUNT

1
2
redis> PFCOUNT databases
(integer) 3

3.PFMERGE

1
PFMERGE destkey sourcekey [sourcekey ...]

将多个 HyperLogLog 合并为一个 HyperLogLog, 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合的并集。合并得出的 HyperLogLog 会被储存在 destkey 键里面, 如果该键并不存在,那么命令在执行之前, 会先为该键创建一个空的 HyperLogLog 。

1
2
3
4
5
6
7
8
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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

 

BitMap、Geo、HyperLogLog的更多相关文章

  1. Redis中3种特殊的数据类型(BitMap、Geo和HyperLogLog)

    前言 Reids 在 Web 应用的开发中使用非常广泛,几乎所有的后端技术都会有涉及到 Redis 的使用.Redis 种除了常见的字符串 String.字典 Hash.列表 List.集合 Set. ...

  2. redis 发布订阅、geo、bitmap、hyperloglog

    1.发布订阅 简介 发布订阅类似于广播功能.redis发布订阅包括 发布者.订阅者.Channel 命令 命令 作用 时间复杂度 subscribe channel 订阅一个频道 O(n) unsub ...

  3. Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用

    Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...

  4. 生物信息大数据&数据库(NCBI、EBI、UCSC、TCGA)

    想系统的学习生信数据库可以先看一下北大的公开课,有一章专门讲的数据库与软件: -生物信息学:导论与方法 北大\ 生物信息数据库及软件资源 一个优秀的生信开发者能够解决如下问题: 如何鉴定一个重要的且没 ...

  5. Android-Drawable、Bitmap、byte[]、资源文件相互转换

    我们在Android的开发中,经常可以遇到图片的处理,当中,有很多是 Bitmap.Drawable.byte[]和资源文件它们直接相互转换. 今天就此总结一下: 1.资源文件转为Drawable 2 ...

  6. Bitmap、CBitmap、HBITMAP以及BITMAP的相互转换

    Bitmap.CBitmap.HBITMAP以及BITMAP的相互转换 构建CBitmapCBitmap bmp;bmp.LoadBitmap(ID); 构建HBITMAPHBitmap = (HBI ...

  7. Bitmap、BitmapDrawable、BitmapFactory、Matrix类之间的关系

    1.BitmapFactory是一个工具类 Bitmap实现在android.graphics包中.但是Bitmap类的构造函数是私有的,外面并不能实例化,只能是通过JNI实例化.这必然是 某个辅助类 ...

  8. Byte[]、Image、Bitmap 之间的相互转换

    原文:Byte[].Image.Bitmap 之间的相互转换 /// <summary>        /// 将图片Image转换成Byte[]        /// </summ ...

  9. Redis in Python:HyperLogLog(pfadd、pfcount、pfmerge)

    redis HyperLogLog 可以接受多个元素作为输入,并给出输入元素的基数估算值. 基数:集合中不同元素的数量.比如 [foo', 'bar', 'foobar', 'bar', 'test' ...

随机推荐

  1. BlockTransferService 实现

    spark的block管理是通过BlockTransferService定义的方法从远端获取block.将block存储到远程节点.shuffleclient生成过程就会引入blockTransfer ...

  2. RabbitMQ技术详解(转)

    RabbitMQ是什么 定义 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python.Ruby..NET.Java.JMS.C.PHP.Action ...

  3. js 鼠标左键拖动滚动

    鼠标左键拖动滚动 原作者: http://blog.csdn.net/lisatisfy/article/details/6606026 本文在源代码的基础上 增加支持水平滚动 的功能 html &l ...

  4. 【k8s】了解一下k8s

    了解一下k8s 地址: https://www.kubernetes.org.cn/doc-11

  5. 一个简单的假vue全家桶(vue+vue-router+require)

    首先说明我觉得这是一个比较好理解的vue全家桶(虽然是假的),模块化也是用require来做的,而且如果后期有必要压缩我也会用gulp来做 1.依赖个个本地模块,require只是用来载入page,这 ...

  6. pkav漏洞之精华部分

    影响巨大的逻辑型漏洞 TOM邮箱任意密码秒改 网易手机邮箱任意密码重置强行绑定 交通银行免费买车漏洞 中国建设银行刷人民币漏洞 腾讯任意QQ号码注册 微信任意用户密码修改漏洞 新浪微搏修改任意用户密码 ...

  7. [Parcel] Running TypeScript with parcel-bundler

    TO get started with TypeScirpt quickly in your local computer is using parcel-bunlder: npm i -g parc ...

  8. 学习ajax总结

    之前公司的ajax学习分享,做一点总结,加深记忆 什么是ajax? 异步的的js和xml,用js异步形式操作xml,工作主要是数据交互 借阅用户操作时间,减少数据请求,可以无刷新请求数据 创建一个对象 ...

  9. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-可以用软件自带NC工具驱动但是程序无法让电机转动怎么办

    新建一个项目,当扫描的时候务必勾选YES,使用网上最新的XML文件   如果不使用,则有些设备可能被扫描出来是无效的(图标不正常)   如果完全删除XML描述文件,可能也能扫描出来,而且可以用Twin ...

  10. Python Socket API 笔记

    将上节中的C#该成Python版的容易程度大大超出了我的意料之外.从来没有发现,仅仅用灰尘简单的几句话就实现了该程序的主要功能,可见python的简易和强大之处.这里先对SocketAPI 做一下总结 ...