Redis四:Redis核心设计原理、Redis K-V 底层设计原理、Redis 渐进式rehash及动态扩容机制、Redis核心编码结构、亿级用户日活统计BitMap实战及源码分析

目录

 

Redis 基本特性

Redis应用场景

RedisDb 数据结构

String

List 

Hash

Set

ZSet

GeoHash

GeoHash算法

GeoHash经纬度编码

点赞关注加收藏!后续内容看下一篇

Redis五:Redis 6.0 新特性、多线程、Client Side Cache、Acls


Redis 基本特性

  1. 非关系型的键值对数据库,可以根据键以O(1) 的时间复杂度取出或插入关联值
  2. Redis 的数据是存在内存中的
  3. 键值对中键的类型可以是字符串,整型,浮点型等,且键是唯一的
  4. 键值对中的值类型可以是string,hash,list,set,sorted set 等
  5. Redis 内置了复制,磁盘持久化,LUA脚本,事务,SSL,  ACLs,客户端缓存,客户端代理等功能
  6. 通过Redis哨兵和Redis Cluster 模式提供高可用性

Redis应用场景

缓存

1s   =1000 ms、 1ms=1000 us、 1us =1000 ns

计数器

可以对 String 进行自增自减运算,从而实现计数器功能。Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。

分布式ID生成

利用自增特性,一次请求一个大一点的步长如 incr 2000 ,缓存在本地使用,用完再请求。

海量数据统计

位图(bitmap):存储是否参过某次活动,是否已读谋篇文章,用户是否为会员, 日活统计。

会话缓存

可以使用 Redis 来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。

分布式队列/阻塞队列

List 是一个双向链表,可以通过 lpush/rpush 和 rpop/lpop 写入和读取消息。可以通过使用brpop/blpop 来实现阻塞队列。

分布式锁实现

在分布式场景下,无法使用基于进程的锁来对多个节点上的进程进行同步。可以使用 Redis 自带的 SETNX 命令实现分布式锁。

热点数据存储

最新评论,最新文章列表,使用list 存储,ltrim取出热点数据,删除老数据。

社交类需求

Set 可以实现交集,从而实现共同好友等功能,Set通过求差集,可以进行好友推荐,文章推荐。

排行榜

sorted_set可以实现有序性操作,从而实现排行榜等功能。

延迟队列

使用sorted_set,使用 【当前时间戳 + 需要延迟的时长】做score, 消息内容作为元素,调用zadd来生产消息,消费者使用zrangbyscore获取当前时间之前的数据做轮询处理。消费完再删除任务 rem  key  member

RedisDb 数据结构

String

String 常用API

  1. /> help @string
  2. /> SET/GET
  3. /> SETNX
  4. /> GETRANGE/SETRANGE
  5. /> INCR/INCRBY/DECR/DECRBY
  6. /> GETBIT/SETBIT/BITOPS/BITCOUNT
  7. /> MGET/MSET

数据结构

 

List 

List常用API

  1. /> help @list  
  2. LPUSH key element [element ...]
  3. RPOP key
  4. RPUSH key element [element ...]
  5. LPOP key
  6. BLPOP key [key ...] timeout
  7. BRPOP key [key ...] timeout
  8. BRPOPLPUSH source destination timeout
  9. RPOPLPUSH  source destination
  10. LINDEX key index
  11. LLEN key
  12. LINSERT key
  13. BEFORE|AFTER pivot element
  14. LRANGE key start stop
  15. LREM key count element
  16. LSET key index element
  17. LTRIM key start stop 

数据结构

List是一个有序(按加入的时序排序)的数据结构

Redis采用quicklist(双端链表) 和 ziplist 作为List的底层实现。

可以通过设置每个ziplist的最大容量,quicklist的数据压缩范围,提升数据存取效率

list-max-ziplist-size  -2        //  单个ziplist节点最大能存储  8kb  ,超过则进行分裂,将数据存储在新的ziplist节点中

list-compress-depth  1        //  0 代表所有节点,都不进行压缩,1, 代表从头节点往后走一个,尾节点往前走一个不用压缩,其他的全部压缩,2,3,4 ... 以此类推

ziplist

quicklist

Hash

Hash常用API

/> help  @hash

  1. HSET key field value [field value ...]
  2. HGET key field
  3. HMGET key field [field ...]
  4. HKEYS key
  5. HGETALL key
  6. HVALS key
  7. HEXISTS key field
  8. HDEL key field [field ...]
  9. HINCRBY key field increment
  10. HINCRBYFLOAT key field increment
  11. HLEN key
  12. HSCAN key cursor [MATCH pattern] [COUNT count]
  13. HSETNX key field value HSTRLEN key field

数据结构

Hash 数据结构底层实现为一个字典( dict ),也是RedisBb用来存储K-V的数据结构,当数据量比较小,或者单个元素比较小时

底层用ziplist存储,数据大小和元素数量阈值可以通过如下参数设置。

ziplist

hash-max-ziplist-entries  512    //  ziplist 元素个数超过 512 ,将改为hashtable编码

hash-max-ziplist-value    64      //  单个元素大小超过 64 byte时,将改为hashtable编码

Set

Set常用API

/> help  @set  

  1. SADD key member [member ...]                
  2. SCARD key                                                  
  3. SISMEMBER key member  
  4. SPOP key [count]  
  5. SDIFF key [key ...]  
  6. SINTER key [key ...]  
  7. SUNION key [key ...]  
  8. SMEMBERS key  
  9. SRANDMEMBER key [count]  
  10. SREM key member [member ...]  
  11. SMOVE source destination member  
  12. SUNIONSTORE destination key [key ...]  
  13. SDIFFSTORE destination key [key ...]  
  14. SINTERSTORE destination key [key ...]  
  15. SSCAN key cursor [MATCH pattern] [COUNT count]

数据结构

Set 为无序的,自动去重的集合数据类型,Set 数据结构底层实现为一个value 为 null 的 字典( dict )

当数据可以用整形表示时,Set集合将被编码为intset数据结构。

两个条件任意满足时 Set将用hashtable存储数据。

  1. 元素个数大于 set-max-intset-entries 
  2. 元素无法用整形表示 

set-max-intset-entries 512       // intset 能存储的最大元素个数,超过则用hashtable编码

intset

整数集合是一个有序的,存储整型数据的结构。整型集合在Redis 中可以保存int16_t,int32_t,int64_t类型的整型数据,并且可以保证 集合中不会出现重复数据。

encoding: 编码类型

length: 元素个数

contents[]: 元素存储

ZSet

ZSet常用API

/> help  @sorted_set  

  1. ZADD key [NX|XX] [CH] [INCR] score member [score member ...]  
  2. ZCARD key  
  3. ZCOUNT key min max  
  4. ZINCRBY key increment member  
  5. ZRANGE key start stop [WITHSCORES]  
  6. ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]  
  7. ZRANK key member   ZREM key member [member ...]  
  8. ZREMRANGEBYRANK key start stop  
  9. ZREMRANGEBYSCORE key min max  
  10. ZREVRANGE key start stop [WITHSCORES]  
  11. ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]  
  12. ZREVRANK key member  
  13. ZSCAN key cursor [MATCH pattern] [COUNT count]  
  14. ZSCORE key member

数据结构

ZSet  为有序的,自动去重的集合数据类型

ZSet 数据结构底层实现为 字典(dict) + 跳表(skiplist) ,当数据比较少时,用ziplist编码结构存储。

zset-max-ziplist-entries  128    // 元素个数超过128 ,将用skiplist编码

zset-max-ziplist-value     64     //  单个元素大小超过 64 byte, 将用 skiplist编码

skiplist

GeoHash

GeoHash算法

GeoHash是一种地理位置编码方法。 由Gustavo Niemeyer 和 G.M. Morton于2008年发明, 它将地理位置编码为一串简短的字母和数字。它是一种分层的空间数据结构,将空间细分为网 格形状的桶,这是所谓的z顺序曲线的众多应用之一,通常是空间填充曲线。

GeoHash经纬度编码

经度范围是东经180到西经180,纬度范围是南纬90到北纬90,我们设定西经为负, 南纬为负,所以地球上的经度范围就是[-180, 180],纬度范围就是[-90,90]。 如果以本初子午线、赤道为界,地球可以分成4个部分。

如果纬度范围[-90°, 0°)用二进制0代表,(0°, 90°]用二进制1代表,经度范围[-180°, 0°)用二进制0代表, (0°, 180°]用二进制1代表,那么地球可以分成如下(左图 )4个部分

通过GeoHash算法,可以将经纬度的二维坐标变成一个可排序、可比较的的字符串编码。 在编码中的 每个字符代表一个区域,并且前面的字符是后面字符的父区域。其算法的过程如下:

根据GeoHash 来计算  纬度的 二进制编码

地球纬度区间是[-90,90], 如某纬度是39.92324,可以通过下面算法来进行维度编码:

  1. 区间[-90,90]进行二分为[-90,0),[0,90],称为左右区间,可以确定39.92324属于右区间[0,90],给标记为1
  2. 接着将区间[0,90]进行二分为 [0,45),[45,90],可以确定39.92324属于左区间 [0,45),给标记为0
  3. 递归上述过程39.92324总是属于某个区间[a,b]。随着每次迭代区间[a,b]总在缩小,并越来越逼近39.928167
  4. 如果给定的纬度(39.92324)属于左区间,则记录0,如果属于右区间则记录1,这样随着算法的进行会      产生一个序列1011 1000 1100 0111 1001,序列的长度跟给定的区间划分次数有关。

纬度产生的编码为1011 1000 1100 0111 1001,经度产生的编码为1101 0010 1100 0100 0100。

偶数位放经度,奇数位放纬度,把2串编码组合生成新串: 11100 11101 00100 01111 00000 01101 01011 00001。

最后使用用0-9、b-z(去掉a, i, l, o)这32个字母进行base32编码,首先将11100 11101 00100 01111 00000 01101 01011 00001转成十进制 28,29,4,15,0,13,11,1,十进制对应的编码就是wx4g0ec1。同理,将编码转换成经纬度的解码算法与之相反

  • 优点: GeoHash利用Z阶曲线进行编码,Z阶曲线可以将二维所有点都转换成一阶曲线。地理位置坐标点通过编码转化成一维值,利用 有序数据结构如B树、SkipList等,均可进行范围搜索。因此利用GeoHash算法查找邻近点比较快
  • 缺点: Z 阶曲线有一个比较严重的问题,虽然有局部保序性,但是它也有突变性。在每个 Z 字母的拐角,都有可能出现顺序的突变。

 

 

点赞关注加收藏!后续内容看下一篇

Redis五:Redis 6.0 新特性、多线程、Client Side Cache、Acls

https://blog.csdn.net/Xx__WangQi/article/details/115216714

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值