doc: 阅读redis文档
This commit is contained in:
@@ -134,6 +134,11 @@
|
||||
- [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)
|
||||
- [Probabilistic](#probabilistic)
|
||||
- [HyperLogLog](#hyperloglog)
|
||||
- [Bloom Filter](#bloom-filter)
|
||||
- [Example](#example-1)
|
||||
- [Reserving Bloom filters](#reserving-bloom-filters)
|
||||
|
||||
|
||||
# redis
|
||||
@@ -2303,5 +2308,90 @@ bitcount的使用示例如下:
|
||||
|
||||
bitmaps可以被轻松的拆分为多个key,通常来讲,也应当避免操作过大的key。将大的bitmap拆分为多个key时,通用策略是`限制每个key`存储`M`个bits,并且通过`{bit-index}/M`来决定当前bit位于哪个key,而`{bit-index} MOD M`则用于当前bit位于key的哪个位置。
|
||||
|
||||
### Probabilistic
|
||||
`Probabilistic data structure`向使用者提供了统计数据的`近似值`,例如`计数、频率、排名`等,而并非精确值。使用Probabilistic data structure可以提高计算效率。
|
||||
|
||||
#### HyperLogLog
|
||||
`HyperLogLog`数据结构用于估计set中的基数,HyperLogLog并不能保证结果的精确性,但是能够提高空间的使用效率。
|
||||
|
||||
> Redis的HyperLogLog实现最多占用12KB空间,并提供了`0.81%`的标准误差。
|
||||
|
||||
通常,统计items中的唯一项个数需要花费的空间和items的个数成正比,但是,有一系列算法可以`牺牲精确性来换取内存使用大小`:
|
||||
- 其能够返回唯一项个数的大致估计值,并且估计值存在标准误差,在redis HyperLogLog的实现中,标准误差小于1%
|
||||
- 在使用该算法时,并不需要使用和items个数成正比的内存空间,而是使用常量大小的内存(在最坏情况下,使用空间大小为12KB,当HyperLogLog中包含元素较少时,其使用的空间也远小于12KB)
|
||||
|
||||
在redis中,HyperLogLog是编码成Redis strings的。故而,对于`HyperLogLog`类型,可以通过`GET`来进行序列化,并通过`SET`来进行反序列化。
|
||||
|
||||
在使用HyperLogLog时,其API如下:
|
||||
- `PFADD`: 可以通过该命令将new item添加到HyperLogLog
|
||||
- `PFCOUNT`: 当想要获取唯一项个数的近似值时,可以调用`PFCOUNT`命令
|
||||
- `PFMERGE`: 如果想要对两个不同的HyperlogLog进行合并,可以使用`PFMERGE`命令
|
||||
|
||||
HyperLogLog的使用示例如下所示:
|
||||
```redis-cli
|
||||
> PFADD bikes Hyperion Deimos Phoebe Quaoar
|
||||
(integer) 1
|
||||
> PFCOUNT bikes
|
||||
(integer) 4
|
||||
> PFADD commuter_bikes Salacia Mimas Quaoar
|
||||
(integer) 1
|
||||
> PFMERGE all_bikes bikes commuter_bikes
|
||||
OK
|
||||
> PFCOUNT all_bikes
|
||||
(integer) 6
|
||||
```
|
||||
HyperLogLog数据结构通常有如下用例场景:统计页面或网站的每天用户访问量
|
||||
|
||||
#### Bloom Filter
|
||||
Bloom Filter也是一种`Probabilistic data structure`,用于检测在set中item是否存在,其使用少量的的固定大小存储空间。
|
||||
|
||||
Bloom Filter并不会将items都存储在set中,相对的,其仅存储item在hash后的结果,故而在部分程度上会牺牲精确性。`通过对精确性的牺牲,Bloom Filter拥有十分高的内存效率,并且其执行效率也很高`。
|
||||
|
||||
`Bloom Filter仅能够保证某元素在set中不存在,但是关于元素的存在其仅能给出一个估计值`:
|
||||
- 当Bloom Filter的返回结果表示某item不存在于set中时,`返回结果是精确的,该item一定在set中不存在`
|
||||
- 但是,如果若Bloom Filter返回结果表示某item存在时,`每N个存在的返回结果就有一个是错误的`。
|
||||
|
||||
Bloom Filter通常用于`negative answer will prevent more costly operations`的场景,例如`用户名称是否被占用,信用卡是否被丢失,用户是否看过广告等`
|
||||
|
||||
##### Example
|
||||
假设自行车生产商已经生产了百万种不同型号的自行车,目前需要`在为新model指定名称时避免指定旧model已经使用过的名称`。
|
||||
|
||||
在该种用例场景下,可以使用bloom filter来检测重复。在如下实例中,创建的bloom filter可容纳100w entries,并且错误率仅为0.1%。
|
||||
|
||||
```redis-cli
|
||||
> BF.RESERVE bikes:models 0.001 1000000
|
||||
OK
|
||||
> BF.ADD bikes:models "Smoky Mountain Striker"
|
||||
(integer) 1
|
||||
> BF.EXISTS bikes:models "Smoky Mountain Striker"
|
||||
(integer) 1
|
||||
> BF.MADD bikes:models "Rocky Mountain Racer" "Cloudy City Cruiser" "Windy City Wippet"
|
||||
1) (integer) 1
|
||||
2) (integer) 1
|
||||
3) (integer) 1
|
||||
> BF.MEXISTS bikes:models "Rocky Mountain Racer" "Cloudy City Cruiser" "Windy City Wippet"
|
||||
1) (integer) 1
|
||||
2) (integer) 1
|
||||
3) (integer) 1
|
||||
```
|
||||
> 在上述示例中,即使bloom filter中仅存在少量元素,返回的`存在`结果也存在误报的可能,即元素其实根本不存在。
|
||||
|
||||
##### Reserving Bloom filters
|
||||
在使用bloom filters时,大部分sizing工作都会自动完成:
|
||||
```redis-cli
|
||||
BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion] [NONSCALING]
|
||||
```
|
||||
- `error_rate`: 该参数代表`false positive rate`,该rate为0和1之间的decimal,例如,当希望的false positive rate为`0.1%`(1 in 1000)时,需要将error_rate设置为0.001
|
||||
- `expected capacity(capacity)`: 该参数代表`bloom filter中期望包含的元素数量`。需要确保该值的准确性:
|
||||
- 如果该值设置过大,其会浪费内存空间
|
||||
- 如果该值设置过小,那么filter被填充满后,`a new one will have to be stacked on top of it (sub-filter stacking)`
|
||||
- `when a filter consists of multiple sub-filters stacked on top of each other`,`其新增操作的延迟仍然会保持不变;但是存在性检查的延迟会增加`
|
||||
- 存在性检查的原理如下:首先,会对top filter检查元素的存在性,如果返回为false,那么会继续检查以一个sub-filter,`该机制会导致存在性检查的延迟增加`
|
||||
- `scaling(EXPANSION)`: 在向bloom filter中添加数据时,并不会因为数据结构的填充而失败。在向filter中添加元素时,error rate也会随之增加。为了保证错误率和bloom filter创建时指定的error rate相近,bloom filter需要自动扩容:`当capacity限制达到时,需要自动创建额外的sub-filter`。
|
||||
- `new sub filter`的size大小等于`last-sub-filter-size * EXPANSION`。
|
||||
- 如果filter中存储的items数量未知,可以将`EXPANSION`设置为`2 or more`,从而减少sub-filters的数量。
|
||||
- 否则,可以将`EXPANSION`设置为`1`,从而减少内存的消耗
|
||||
- 默认的EXPANSION为2
|
||||
> 在向filter中添加new sub-filter时,相比于前一个filter,会为new sub-filter分配更多的hash function
|
||||
|
||||
- `NONSCALING`: 如果想要禁用scale,可以指定`NONSCALING`。如果达到了initially assigned
|
||||
Reference in New Issue
Block a user