特征:
In-memory type
Key-Value pair (Value 可以定义本地方法)
The worker thread is single-threaded; there might be more IO threads
Persistent
同步
集群 → 中间件(本地的,分布式)
查询状态
多路复用器
Linux 里面用的是 epoll
Receive and read
计算
比较同类型(技术选型)
Memcached: value can only be string.
However, you can serialize more complicated structure
全量IO
Need to deserialize,浪费 client 计算力
数据向计算移动
Redis: value可以是hashset, list, etc
V: function
E.g. Index(n)
计算向数据移动,(弊端:移动数据成本大于移动计算)
单线性:需要串行
Read client1 -> calc client 1 -> write client 1 -> read client 2 -> calc client 2 -> write client 2
单线程,串行不一定慢!
E.g. 秒杀情景:高并发 vs 并行度
Loads of requests -> Load balancer -> Multi Servers -------> 数据库?
看上去servers是并行的,但实际上因为数据库lock,几乎是串行的
Loads of requests -> Load balancer -> Multi Servers ---func: decr----> Redis
Redis内部是串行
单线程弊端:只能用一个cpu,不能发挥硬件
如何解决?
增加io threads (read and write),worker thread还是 single-threaded
Netty
问题:IO顺序?
IO 执行在kernel上是无序的
但是!在一个request里面是有序的:
无状态协议 e.g. http
通信的层次:3
业务应用层次:可以加 uniqle identifier 来识别消息,以此保证顺序
Load balancing: 亲密度/粘性
Redis的5大Value类型解析
注意使用场景
String
String, append, strilen -> json,图片,文件 -> 内存级的文件系统(静态小文件),分布一致性/服务无状态
数值 incr, decr
Bitmap
二进制安全:redis自己不会做编码/解码,需要提供字节数组, 同理 zookeeper, hbase, kafka
需要统一编码 (utf-8)
Bitmap 设计拓展:
setbit [key] [offset] [value]
用户统计:
任意时间窗口,给出登录天数?
存储时是明细全量时点数据,要是用数据库,超级难 aggregation
但是使用redis bitmap,每个bit可以1 or 0,如果告知offset and length,就可以直接得出登录天数
活跃用户数
用日期作为key
使用or在bit上的操作,可以得出在时间窗口里面每天都登陆的活跃用户
List
底层:Double linked list
可以从left push/ pop, 可以right push/pop
可以模拟 queue 和 stack
[lindex]: 数组
微服务需要stateless
自身不带private fields,只有methods
Private fields 可以放在redis里面被share
Hash
E.g.
set zsquared::name zz
set zsquared::age 18
hset zsquared name zz
hset zsquared age 18
hgetall zsquared → name, zz, age, 18
hkeys zsquared → name, agh
hvals zsquared → zz, 18
Set
去重,无序,用于交集并集差集
在集群里不推荐使用,或者单独设置set redis:如果在redis集群里面被分散,集合操作会伴随大量IO,干扰性能
应用场景:朋友圈交集,共同好友,推荐好友
srandmember: 随机取出无序,参数>0的时候会保证去重,<0时不保证
sunion, sinter, sdiff (left join, right join, inner join)
Sorted Set/ ZSet
zadd k1 2.2 apple 3.3. orange 1.1 banana → 这里的score是float,有精度差
zrange k1 0 -1 withscores → 从小到大
zrevrange k1 0 -1 withscores → 从大到小
Redis这些方程,能让计算向数据流动
如何保持顺序: skiplist
最底下就是普通的linked list
造层是随机的,每层间隔也随机,上面的层也是linked list,相当于2分法方便快速insert(insert 时已经排序了)
Linux系统的支持:fork、copy on write
Redis的持久化:RDB、AOF、RDB&AOF混合使用
Persistance:
Snapshot rdb 恢复快,缺失多
日志 aof 完整 (慢,冗余)
1)每次操作,完整IO,但是性能下降一半!
2)每秒,buffer and flush to disk,丢失小于一个buffer
3)靠kernel buffer and flush,丢失一个buffer,经验数据是2G
混合使用:
E.g. 8点take a snapshot,然后写日志 aof 追加增量;9点再take a snapshot,抹去之前日志(减量)
Redis 到底做数据库还是cache?
只是cache需要持久化么?需要,要不然重启期间request会击垮数据库
生产系统之中的问题:
Single point of failure: Master-slave mirror cluster,同步
Pressure test: Sharded cluster,不需要同步
通过Redis学AKF划分原则、CAP定理
Pressure test: Sharded cluster,不需要同步
强一致性,弱一致性
PAXOS 算法(一半)
AKF划分(可用于DB, Redis, web service)
X dimension: master-slave cluster 冗余
Y dimension: divided by business purpose 业务划分
Z dimension: sharding → 去哪台fetch data?
How to shard?
客户端可以给出映射算法,缺点:所有客户端要统一算法
来一个proxy统一算法,但是single point failure
Redis 自带 算法,映射,虚槽位
Redis vs zookeeper分布式锁的探索
No comments:
Post a Comment