BitMap操作命令
BitMap是一种新的数据类型。该数据类型本质上就是一个仅包含0和1的二进制字符串。其相关命令都是对这个字符串二进制位的操作。
用于描述该字符串的属性由三个:key、offset、bitValue。
- key:BitMap类型对应得key(因为Redis是key-value型)
- offset :BitMap是一个字符串,其中每个字符都有对应得索引,这个索引就是字符在BitMap中的偏移量offset,这个offset的范围是【0,232-1】
- bitValue:BitMap数据都是一个仅包含0和1的二进制字符串,每个offset位上字符称为bitValue。bitValue的值非0即1。
============================================================
- setbit: 为给定key的BitMap数据的offset位置设置值为value。返回值为修改前该offset位置的bitValue。
格式:setbit key offset value
注意:对于原BitMap中不存在的offset进行复制,字符串会自动伸展以确保它可以将value保存在指定offset上。
字符串伸展时,空白位置以0填充 。需要注意的是,对使用较大offset的setbit操作。内存分配过程可能会造成Redis服务器阻塞。
- getbit:获取指定offset上的位置bitValue
- bitcount:统计字符串中bitValue为1的bit位数量。一般是统计整个字符串,也可以指定额外的start和end参数,实现对指定范围字符串的统计,包括start和end在内。注意:这里的start和end的单位是字节,不是bit,并且从0开始计数。
格式:bitcount key 【start】 【end】
注意:start和end可以使用负数,-1表示最后一个字节,-2表示倒数第二个。
对于不存在的key。被当成空字符来处理,因此不存在的key进行bitcount操作的结果为0.
- bitpos :返回BitMap中第一个值为指定值的二进制位的位置,默认是检测整个BitMap。也可以指定要检测的范围。
格式:bitpos key bit 【start】 【end】
- bitop:对一个或多个BitMap 进行二进制位操作,并将结果保存到destkey上。
格式:bitop operation destkey key【key...】
说明:operation 可以是and、or、not、xor 这四种:
- and:对一个或多个BitMap 执行按位与操作,
- or:对一个或多个BitMap 执行按位或
- xor:对一个或多个BitMap 执行按位异或
- not:对一个或多个BitMap 执行按位异非
除了not操作之外,其他操作都可以接收对一个或多个BitMap
除了not操作之外,其他对一个BitMap的操作其实就是一个复制。
如果参与运算的多个BitMap长度不同,较短的BitMap会以0作为补充位与较长的计算。
应用场景
由于offset的取值范围很大,所以一般应用于大数据量的二值性统计。
例如平台活跃用户统计(访问或未访问)、支持率、考勤统计、图像二值化等。
不过,对于数据量较小的二值性统计并不适合BitMap,使用Set更为合适。
HyperLogLog操作命令
HyperLogLog 数据类型是一种超级日志记录。
该数据类型可以简单理解成一个set集合,集合元素为字符串。
实际上HyperLogLog 是一种基数计数概率算法,通过该算法可以利用极小的内存完成独立总数的统计。
- pfadd:将任意数量的元素添加到HyperLogLog 集合里面
格式:pfadd key element 【element...】
- pfcount:该命令作用于单个key时,返回这个key的HyperLogLog 集合的近似基数(元素个数);
作用于多个key时,返回所有key的HyperLogLog 集合的并集的近似基数。
格式:pfcount key 【key...】
- pfmerge:将多个集合合并成一个集合,并存储到destkey,合并后的HyperLogLog 的基数接近于所有的HyperLogLog 集合的并集。
格式:pfmerge destkey sourcekey [sourcekey ...]
应用场景
HyperLogLog 可对数据量超级庞大的日志数据做不精确(误差0.81%)的去重计数统计。
对于平台上每个页面每天的UV数据,非常适合使用HyperLogLog 进行记录。
Geospatial操作命令
Geospatial 地理空间,本质上还是一种集合,只不过集合元素是一种由三部分构成的数据结构,这种数据结构称为空间元素:
- 经度:longitude。有效经度为【-180,180】.正的表示东经,负的表示西经。
- 纬度:latitude。有效维度为【-85.05112878,85.05112878】正的表示北纬,负的表示南纬
- 位置名称:也称为该85.05112878集合的空间元素名称。
该类型可以设置、查询地理位置的经纬度,查询某范围内的空间元素,计算两个空间元素间的距离等。
- geoadd:将一个或多个空间元素添加到集合中
格式:groadd key longitude latitude member 【 longitude latitude member...】
- geopos:从指定的地理空间中返回指定元素的位置,即经纬度
格式:geopos key member [member...]
- geodist:返回2个位置之间的距离。其中unit必须是以下单位的一种:m(米,默认)、km、mi(英里)、ft(英尺)
格式:geodist key member1 member2 [unit]
- geohash:返回一个或多个位置元素的geohash值。
格式:geohash key member 【member...】
说明:geohash是一种地址编码方法,它能把二维的空间经纬度数据编码成一个字符串,该值主要用于底层应用或者调试,实际作用不大。
-
georadius:以指定的经纬度为中心,返回指定地理空间中包含的所有位置元素中,与中心举例不超过半径的元素,返回时还可以携带额外信息:
- withdist:返回时携带位置元素与中心之间的距离,单位和用户给定的范围单位保持一致。
- withcoord:将位置元素的经纬度也返回
- withhash:将位置元素的geohash也返回,不过这个hash以整数形式表示。
命令默认返回未排序的位置元素。可通过以下两个参数指定返回位置元素的排序方式:
- asc:根据中心位置,从近到远的方式排序
- desc:根据中心位置,从远到近的方式排序
返回结果包含中心点元素。
格式:georadius key longitude latitude radius 【unit】【withcoord】【withdist】【withhash】【asc|desc】 [count]
- georadiusbymember:和上面命令一样,只是该命令的中心是由位置元素给定的,而不是经纬度。
格式:georadiusbymember key member radius 【unit】【withcoord】【withdist】【withhash】【asc|desc】 [count]
应用场景
微信发现中的"附近"功能,钉钉签到功能等。
发布/订阅命令
消息系统
发布/订阅(pub/sub) 是一种消息通信模式:
发布者(消息生产者)生产和发送消息到存储系统;
订阅者(消息消费者),从存储系统接收和消费消息。
这个存储系统可以是文件系统FS、消息中间件MQ、数据库管理系统DBMS,也可以是Redis。
订阅者订阅消息后,只要存储系统中有该类消息,就可以不断的接收并消费这些消息。
当存储系统中没有消息后,订阅者就会阻塞。
当发布者将消息写入存储系统后,会立即唤醒订阅者。
当存储系统放满时,不同的发布者有不同的处理方式:有的会阻塞发布者发布,有的会将多余消息丢失。
不同的消息系统的发布/订阅方式不同:
RocketMQ、KAfka等消息中间件构成的消息系统,消息是以主题Topic分类的
Redis'则是以频道channel分类的。
- subscribe: Redis客户端(消费者)通过此命令可以同时订阅任意数量的频道。在输出了主题后,命令处于阻塞状态,等待相关频道的消息。
格式:subscribe channel 【channel...】
- psubscribe : 订阅一个或多个符合给定模式的频道
格式:psubscribe pattern [pattern...]
比如:psubscribe news.*
说明:这里的模式只能使用通配符*。
- publish:发布一个频道消息,返回值为接收到该消息的订阅者·数量。
格式:publish channel message
- unsubscribe : 退订指定的频道
格式:unsubscribe 【channel 【channel...】】
说明:如果没有频道被指定,那么客户端退订所有频道,这种情况会返回一个信息,告知客户端所有被退订的频道。
-
punsubscribe:退订一个或多个符合给定模式的频道。效果和unsubscribe 相同。
-
pubsub:查看订阅/发布系统状态的内省命令集。
- pubsub numpat:查询当前Redis所有客户端订阅的所有频道模式的数量总和。
- pubsub channels: 列出当前所有的活跃频道(至少有一个订阅者的频道)
格式:pubsub channels 【pattern】
说明:pattern参数可选,如果不指定pattern参数,会列出所有的活跃频道,
如果给出pattern参数(只能使用通配符*),只列出相匹配的活跃频道。
- pubsub numsub: 返回给定频道的订阅者数量。不给定任何频道就返回一个空列表。
Redis事务
Redis事务本质是一组命令的批处理。这组命令在执行过程中会被顺序地、一次性全部执行完毕,只要没出现语法错误,这组命令在执行期间是不会被中断的。
Redis事务特性
Redis事务不具有ACID特性,仅保证了数据的一致性!
- 这组命令中的某些命令的执行失败不影响其他命令的执行,不会引发回滚。不具备原子性。
- 这组命令通过乐观锁机制实现了简单的隔离性。没有复杂的隔离级别。
- 这组命令的执行结果是被写入到内存,是否持久取决于Redis的持久化策略,与事务无关。
Redis事务实现
三个命令
Redis事务通过三个命令进行控制:
- muti:开启事务,进入队列等待执行。
- exec:执行事务
- discard:取消事务
具体应用:
Redis事务异常处理
语法错误:整个事务作废,全部不执行;
运行时错误 :错的报错,对的照常执行,无自动回滚;
WATCH 冲突 :事务放弃,业务层循环重试;
Redis事务隔离机制
使用乐观锁实现事务隔离。
Redis通过watch命令再配合事务实现了多线程下的隔离操作。
实现原理:
- 当一个客户端对key执行了watch后,就给key添加一个version乐观锁,并初始化version。初值为1.
- 客户端c做对key的修改命令写入到事务队列中,将该key的value和version进行了读取并保存,此时version=1
- 客户端c右对key进行了修改,改变了value,也改变了version=2
- 客户端c左执行exec,在执行之前将当前客户端缓存中的version和当前key的version 进行比较,发现不相等,说明当前客户端缓存的key'的value已被修改,所以不执行写操作。