diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index 05d81cf..8019325 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -126,6 +126,14 @@ - [zero length streams](#zero-length-streams) - [Total latency of consuming a message](#total-latency-of-consuming-a-message) - [The model redis uses in order to route stream messages](#the-model-redis-uses-in-order-to-route-stream-messages) + - [Redis Geospatial](#redis-geospatial) + - [Bike Rental stations Example](#bike-rental-stations-example) + - [Redis bitmaps](#redis-bitmaps) + - [Example](#example) + - [Bit Operations](#bit-operations) + - [single bit operations](#single-bit-operations) + - [operations on group of bits](#operations-on-group-of-bits) + - [longest streak of daily visits](#longest-streak-of-daily-visits) # redis @@ -2214,5 +2222,86 @@ redis通过如下方式来管理`blocking operation waiting for data`: 上述model是push-based的,将消息添加到consumer buffers的操作将直接由`XADD`调用来执行。 +### Redis Geospatial +redis geospatial支持对坐标进行存储和查询,该数据结构主要用于`find nearby points within a given radius or bounding box`。 + +#### Bike Rental stations Example +假设当前需要支持`基于当前位置查找最近的bike rental station`功能,如下是redis geospatial的示例。 + +```redis-cli +> GEOADD bikes:rentable -122.27652 37.805186 station:1 +(integer) 1 +> GEOADD bikes:rentable -122.2674626 37.8062344 station:2 +(integer) 1 +> GEOADD bikes:rentable -122.2469854 37.8104049 station:3 +(integer) 1 +``` +在上述示例中,向geospatial index中添加了多个自行车租赁点的location。 + +```redis-cli +> GEOSEARCH bikes:rentable FROMLONLAT -122.2612767 37.7936847 BYRADIUS 5 km WITHDIST +1) 1) "station:1" + 2) "1.8523" +2) 1) "station:2" + 2) "1.4979" +3) 1) "station:3" + 2) "2.2441" +``` +而在上述命令中,则是`find all locations within a 5 kilometer radius of a given location`,并对每个location都返回了对应的距离 + +### Redis bitmaps +在redis中,bitmaps并不是实际的数据结构,而是针对String类型的一系列`bit operations`,bitmaps的对外表现为和`bit vector`类似。 + +对于bitmaps其最大大小为`512MB`,其最多可以包含`2^32`个不同的bits。 + +redis支持对一个或多个strings执行位运算 + +#### Example +假设存在1000个骑行运动员正在乡间竞速,并且他们的自行车上装有编号为`0~999`的传感器,并需要检查在当前小时传感器是否ping过服务器,以此来确认运动员状态。 + +该场景可以适用bitmap,bitmap的key代表current hour: +- Rider 123在`2024-01-01 00:00:00`时刻ping过server,此时可以通过`setbit`命令将123代表的bit置位 +- 可以通过`GETBIT`命令来检查是否rdier 456在一小时内ping过server + +```redis-cli +> SETBIT pings:2024-01-01-00:00 123 1 +(integer) 0 +> GETBIT pings:2024-01-01-00:00 123 +1 +> GETBIT pings:2024-01-01-00:00 456 +0 +``` +#### Bit Operations +Bit Operations分为两种类型: +- `single bit operations`: 例如将某个bit改为0或1,或获取某个bit的值 +- `operations on groups of bits`: 例如counting the number of set bits in a given range of bits + +bitmap的一个巨大优势是其能够在存储信息的同时极大的节省存储空间。对于存储single bit information,其能够在`512MB`的空间限制下存储`4 billion`位的值。 + +##### single bit operations +- `SETBIT`: SETBIT命令的第一个参数为bit number,而第二个参数为`0或1`。如果`addressed bit is outside the current string length`,那么该SETBIT操作将自动拓展string的长度 +- `GETBIT`: GETBIT命令会返回指定位置bit的值。`out of range bits`(addressing a bit that is outside then length of the string stored into the target key)其值将会被视为`0` + +##### operations on group of bits +redis支持对`group of bits`进行如下操作: +- `BITOP`: `performs bit-wise operations between different strings`。支持的operators有`AND, OR, XOR, NOT, DIFF, DIFF1, ANDOR, ONE` +- `BITCOUNT`: 该命令用于统计置为1的bit个数 +- `BITPOS`: 该命令用于查找`the first bit having specified value of 0 or 1` + +bitcount和bitpos都支持对bitmap的指定范围来进行操作,`该范围可以通过bit或byte来指定,从0开始`,默认情况下,范围指是基于`BYTE`的,如果要基于`BIT`指定范围,需要手动指定`BIT` option。 + +bitcount的使用示例如下: +```redis-cli +> BITCOUNT pings:2024-01-01-00:00 +(integer) 1 +``` + +##### longest streak of daily visits +可以通过bitmap来记录用户的最长连续访问时间。可以用0来表示`the day you made your website public`,并且`set the bit every time the user visits the web site`。`bit index`则是当前时间基于`day 0`已经经过的天数。 + +这样,针对每个user,都通过一个small string来存储了用户的访问记录。并且,可以简单的计算用户的最长连续访问天数。 + +bitmaps可以被轻松的拆分为多个key,通常来讲,也应当避免操作过大的key。将大的bitmap拆分为多个key时,通用策略是`限制每个key`存储`M`个bits,并且通过`{bit-index}/M`来决定当前bit位于哪个key,而`{bit-index} MOD M`则用于当前bit位于key的哪个位置。 +