Redis知识整理

价值与场景

Redis 这么火,它都解决了哪些问题?
问题场景:接口慢
方案1:消费者端缓存(cache-control:max-age)——旧数据,依然有大量新请求
方案2:基于本机内存的1分钟缓存——旧数据,单机内存不够
方案3:Redis单机服务器——挂了就缓存丢失、造成重启和恢复中的雪崩
方案4:Redis持久化——缓解重启时的大量重新请求
方案5:Sentinel和Replication——缓解Redis挂了的问题

  • Sentinel可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能;是对Redis的发布和订阅功能的一个利用。
  • Replication则是负责让一个Redis服务器可以配备多个备份的服务器。Redis也是利用这两个功能来保证Redis的高可用的。

方案6:集群——解决单机资源有限问题

  • Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
  • Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

常用数据结构

String,Hash,List,Set,Sorted Set
https://my.oschina.net/xsh1208/blog/2218494

  • String
    可变的字节数组
    会多分配空间字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间
# get set strlen 
# getrange 获取子串
# setrange 设置子串
# append 追加
# 没有删除子串,和插入子串

# 计数器
> set ireader 42
OK
> get ireader
"42"
> incrby ireader 100
(integer) 142
> get ireader
"142"
> decrby ireader 100
(integer) 42
> get ireader
"42"
> incr ireader  # 等价于incrby ireader 1
(integer) 143
> decr ireader  # 等价于decrby ireader 1
(integer) 142

> expire ireader 60
(integer) 1  # 1表示设置成功,0表示变量ireader不存在
> ttl ireader
(integer) 50  # 还有50秒的寿命,返回-2表示变量不存在,-1表示没有设置过期时间
> del ireader
(integer) 1  # 删除成功返回1
> get ireader
(nil)  # 变量ireader没有了
  • list
    双向链表实现(数据量少是ziplist,数据量大是quicklist(把连续的内存空间(ziplist)连起来而非对每个元素都用指针连,后者太费空间))。可用作队列、堆栈
rpush
rpop
lpush
lpop
llen
lset
lrange
linsert xxx before a b# linsert指令并不是通过指定位置来插入,而是通过指定具体的值
lrem l_name n object# 删除
blpop # 阻塞pop
lindex # 随机读
  • hash
    和Java的HashMap数据结构一致
# 增加元素
> hset ireader go fast
> hmset ireader java fast python slow # 添加多个
# 获取元素
> hmset ireader go fast java fast python slow
OK
> hget ireader go
"fast"
> hmget ireader go python
1) "fast"
2) "slow"
> hgetall ireader
1) "go"
2) "fast"
3) "java"
4) "fast"
5) "python"
6) "slow"
> hkeys ireader
1) "go"
2) "java"
3) "python"
> hvals ireader
1) "fast"
2) "fast"
3) "slow"
#删除元素
> hmset ireader go fast java fast python slow
OK
> hdel ireader go
(integer) 1
> hdel ireader java python
(integer) 2
# 是否存在
> hexists ireader go
(integer) 1

hash也可做计数器

  • Set
    Java的HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构
> sadd ireader go java python # 插入
(integer) 3
# 读取
> smembers ireader
1) "java"
2) "python"
3) "go"
> scard ireader
(integer) 3
> srandmember ireader
"java"
# 删除
> sadd ireader go java python rust erlang
(integer) 5
> srem ireader go java
(integer) 2
> spop ireader
"erlang"
# 元素是否存在
> sismember ireader rust
(integer) 1
> sismember ireader javascript
(integer) 0
  • ZSet(SortedSet)

SortedSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层实现使用了两个数据结构,第一个是hash,第二个是跳跃列表,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。跳跃列表的目的在于给元素value排序,根据score的范围获取元素列表。

# 增加1-N个value/score对
> zadd ireader 4.0 python
(integer) 1
> zadd ireader 4.0 java 1.0 go
(integer) 2
# 获取排名
> zscore ireader python
"5"
> zrank ireader go  # 分数低的排名考前,rank值小
(integer) 0
> zrank ireader java
(integer) 1
> zrank ireader python
(integer) 2
> zrevrank ireader python
(integer) 0
# 操作很多,不一一列举

跳表很重要!

高级数据结构

https://blog.csdn.net/wufaliang003/article/details/82016385

  • Bitmaps
127.0.0.1:6380> setbit dupcheck 10 1
(integer) 0
127.0.0.1:6380> getbit dupcheck 10 
(integer) 1
  • Hyperloglogs
    涉及数学,不太理解
  • GEO
    地理位置信息,经纬度
  • Pub/Sub主题订阅者模式
    实现1对N的消息订阅
    缺点:消费者下线的情况下,生产的消息会丢失,要用专业的消息队列如rabbitmq等。

底层数据结构

进阶

Redis Module
1.BloomFilter
2.RedisSearch
3.Redis-ML

分布式锁

先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。

  • 如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
    这个锁就永远得不到释放了。set指令有非常复杂的参数,是可以同时把setnx和expire合成一条指令来用.

核心原理与源码分析

http://zhangtielei.com/posts/blog-redis-how-to-start.html

  • Redis的事件循环(Event Loop)的机制,关系到:

为什么Redis是单线程执行却能同时处理多个请求?(当然严格来说Redis运行起来并非只有一个线程,但除了主线程之外,Redis的其它线程只是起辅助作用,它们是一些在后台运行做异步耗时任务的线程)

Redis的main函数开始执行后的逻辑可以分为两个阶段:
1.各种初始化(包括事件循环的初始化);
2.执行事件循环。

image.png

这几个部分也很重要,有时间再细细了解

  1. 持久化
  2. PipeLine
  3. 同步机制

底层数据结构:
https://www.cnblogs.com/ysocean/p/9080942.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • 1、redis是什么: Redis is an open source, BSD licensed, advanc...
    huangxiongbiao阅读 1,655评论 0 2
  • Redis的内存优化 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。 Redis所有的数据都...
    meng_philip123阅读 18,887评论 2 29
  • 参考来源 Redis的内存优化 Redis所有的数据都在内存中,而内存又是非常宝贵的资源。对于如何优化内存使用一直...
    秦汉邮侠阅读 1,286评论 0 2
  • 首先redis是一个基于内存的nosql中间件,有五种数据结构,支持持久化,常用来做缓存,分布式锁等,相比于同类产...
    NaLiu阅读 157评论 0 0
  • 教你看懂redis配置 – 安全 我们可以要求redis客户端在向redis-server发送请求之前,先进行密码...
    烨枫_邱阅读 309评论 0 1