Redis原理及实现细节(1)命令和数据结构

Redis(Remote Dictionary Service)远程字典服务,内存数据库,kv数据库,数据结构数据库

http://redis.cn/commands.html

1. 应用:

朋友圈点赞数、评论、点击数(hash)

记录朋友圈说说列表(排序)、快速显示(list)

记录文章的标题、摘要、作者和封面,列表页显示(hash)

朋友圈点赞用户ID、评论ID、显示去重计数(zset)

缓存热点数据,减少数据库压力(hash)

朋友圈说说id(计数器string)

集合交并差记录好友关系(set)

游戏战绩(list)

2. 数据结构&存储结构

string:二进制安全字符串(长度 = std::string)

hash:散列表/字典(=unordered_map)【核心】

list:首尾相接双向队列

set:集合(无序唯一)

zset:集合(有序唯一)【核心——分布式定时器、限流】

 3. value编码规则

内存分配器认为,小于64byte=小字符串,大于64byte=大字符串

4. 使用

redis-server //开启Redis服务器

redis-cli -h 127.0.0.1 -a 123456 //开启Redis客户端


string

  • 字符数组,动态字符串,长度小于1M时,加倍扩容;超过1M每次多扩容1M;最大长度为512M
  • 二进制安全字符串,可以存图片、二进制协议等数据
  • 字符串长度小于20且能转为整数,用int存储;字符串长度小于等于44,用embstr存储;字符串长度大于44,用raw存储

SET     GET     INCR     INCRBY     DECR     DECRBY     DEL      SETNX                 

设置      获取   原子+1    原子+num   原子-1    原子-num    删除     设置不存在的key

SETBIT key offset value          GETBIT key offset                              BITCOUNT key

设置value在offset偏移的bit值   返回key对应string在offset位的bit值   统计bit1的个数

应用:对象存储 、累加器(incr reads)、分布式锁(setnx lock 1)、位运算

list

  • 双向链表实现,列表首尾操作(删除和增加)时间复杂度 O(1) ;查找中间元素时间复杂度为O(n) 
  • gzip压缩:元素长度小于48不压缩;元素压缩前后长度差不超过8,不压缩(存储:双向列表、压缩列表)

LPUSH     LPOP     RPUSH     RPOP     LRANGE     LREM     BRPOP     DEL

LRANGE key start end     LREM key count value     BRPOP key timeout 队列为空时阻塞(超时时间s+延时队列)

应用:栈(LPUSH+LPOP) 队列(LPUSH+RPOP) 阻塞队列(LPUSH+BRPOP/RPUSH+RLPOP)

异步消息队列(web和server之间使用redis)获取固定窗口记录(LPUSH+LTRIM lists 0 4 固定长度为5)

 hash

  • 散列表,在很多高级语言当中包含这种数据结构;c++ unordered_map 通过 key 快速索引value;
  • 节点数量<=512且字符串长度<=64用压缩列表存储,否则字典存储

HGET     HSET     HMSET     HMGET     HINCRBY     HLEN     HDEL

应用:存储对象,购物车 

set

  • 集合, 用来存储唯一性字段,不要求有序;(存储是有序的,但是使用过程中不要求有序)
  • 元素为整数且节点数量<=512 用整数数组存储,元素有一个不是整数或数量大于512用字典存储

SADD     SCARD     SMEMBERS     SISMENBER     SRANDMEMBER     SPOP     SDIFF     SINTER     SUNION

key加member 计算个数  返回成员   判断是否为成员   随机返回成员      移除并返回   求集合的成员差集  交集  并集

 应用:抽奖,共同关注,推荐好友

zset

有序集合;用来实现排行榜;它是一个有序唯一(member唯一)结构  【zset:  集合key 分数score 成员member】

数量>128或有一个字符串长度>64,跳表存储;子节点数量<=128且字符串长度<=64压缩列表存储

数量少,压缩列表,节省空间O(n);数量多时,访问性能,O(1) O(logn).

ZADD                                      ZREM     ZSCORE     ZINCRBY     ZCARD     ZRANK     ZRANGE     ZREVRANGE

给集合key添加score-member 删除       返回score    score增量       元素个数  返回排名   返回范围内元素   返回逆序

应用:百度热榜、延时队列(zset的有序性,到期时间作为score,在分布式系统:分布式定时器)、 

时间窗口限流 (限定userid在period中发生action的max_count)

延时队列:如果一件事A交给B处理,B在指定时间内未完成,就把任务转发给C或回退给(回退、转发方法),可以使用延时队列来实现。A分配给B任务时,把当前时间的记录放入延时队列,获取到超时记录就执行转发或回退删除操作。

一般,加锁失败有几种处理办法:

1、直接抛出异常,通知用户稍后重试;

2、sleep 一会再重试;

3、将请求转移至延时队列,过一会再试;

使用zset来实现延时队列,用到了zset的有序性,把到期时间作为score,zrangebyscore找出到期任务,执行zrem删除。

为了避免多线程竞争,可以采用lua脚本原子执行这两个命令,避免多个线程同时获取到任务,但是无法删除,白执行了操作。

解决:漏斗限流


时间窗口限流:系统限定用户的某个行为在指定的时间里只能发生N次

维护一次时间窗口,将窗口外的记录全部清理掉,只保留窗口内的记录;
缺点:记录了所有时间窗口内的数据,如果这个量很大,不适合做这样的限流

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值