Wednesday, July 8, 2020

Dig a little bit deeper into Redis...

特征:

In-memory type

Key-Value pair (Value 可以定义本地方法)

The worker thread is single-threaded; there might be more IO threads

Persistent

同步

集群 → 中间件(本地的,分布式)

 

 

  1. 查询状态

多路复用器

Linux 里面用的是 epoll

  1. Receive and read

  2. 计算

 

 

比较同类型(技术选型)

Memcached: value can only be string.

However, you can serialize more complicated structure 

  1. 全量IO

  2. 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: 

  1. Snapshot rdb 恢复快,缺失多

  2. 日志 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

Most Recent Posts