最近写的一个分布式缓存, 感兴趣的可以
https://github.com/Leviathan1995/grape
兼容 Redis 协议, 因为 Redis 协议数据表现力很强, 但是集群的使用需要主从模式,所以考虑写一个完全 P2P 结构的分布式缓存, 通过一致性哈希分散数据, 使用客户端连接集群里任意节点就能进行服务,使用redis_cli
新增节点和删除节点都特别简单.
目前支持的命令只有 SET,GET,后面慢慢加.
TTL
因为没有 master 的概念, 现在最主要的就是考虑如何实现节点的存活检测, 考虑要不要也像 Redis 加入哨兵机制,这个问题欢迎大家一起讨论...
1
NullMan 2017-09-29 15:40:33 +08:00
问个问题,用 redis_cli 删除一节点后,这被删除的节点的数据怎么个处理了?
|
2
qiyue201707 OP @NullMan 目前的情况是数据就没有了,但这个问题后面我会改成集群里存在备份节点,删除一个节点后,更新整个集群里所有的节点的路由表,之后每次的服务就移动到备份节点了, 因为是缓存,我觉得数据是允许丢失的
|
3
NullMan 2017-09-29 16:48:30 +08:00
@qiyue201707 我认为删除就是删除了,既然要删除一个节点,就说明已经容许数据丢失,就如你说的 “因为是缓存,我觉得数据是允许丢失的。”
当然,这是设计上的问题,主要看你怎么定义 “删除节点”。 |
4
qiyue201707 OP @NullMan 删除节点也有可能节点不可用了
|
5
Allianzcortex 2017-09-29 16:52:26 +08:00 via iPhone
LZ 在 infra 方向真是我辈楷模啊
|
6
qiyue201707 OP @Allianzcortex 楷模谈不上....本身就是个基础架构方向的新兵,现在还在学习阶段....
|
7
Allianzcortex 2017-09-29 17:03:03 +08:00
@qiyue201707 太谦虚了......新建了一个 V2 账号吗?
|
8
Allianzcortex 2017-09-29 17:03:36 +08:00
@NullMan @qiyue201707 我是觉得缓存这类本身的特性决定了要选择 C 而非 A,就算是穿透了也有后面的数据库兜底 /(ㄒoㄒ)/~~emmmmmm
|
9
qiyue201707 OP @Allianzcortex 是换了一个账号,不想暴露太多个人信息...
关于是否添加备份节点可以通过配置项让使用者自己决定,尽可能的提高容灾 |
10
neoblackcap 2017-09-29 17:22:29 +08:00
我想问一下使用问题
1. 是不是我连接的时候还是需要指定节点的 ip ? 2. 节点挂了是不是要自己重新连接? 还有就是这个缓存的数据一致性是怎么样? |
11
qiyue201707 OP |
12
Allianzcortex 2017-09-29 17:44:07 +08:00
@neoblackcap 这个版本是 decentralized,所以没有类似 paxos/raft 的 master/slave 选主,所以数据只有 0 和 1 两种状态,是吧 @qiyue201707
|
13
qiyue201707 OP @Allianzcortex 是的
|
14
movistar 2017-09-29 17:49:46 +08:00
实际上就是对 key 做数据一致性哈希分桶?
存储节点互相独立,互不影响么 一般来说分布式服务都需要一个 meta server 吧,或者 name server 如何避免一台服务器宕机后导致的内存穿透问题呢 如果只是简单的做了分桶,为啥不直接在 client 侧根据 hash 结果选择不同 redis 连接呢 redis 还有主备,能保证一个节点宕机另一个可用 |
15
qiyue201707 OP @movistar 缓存穿透问题加备份节点就能尽可能解决
client 根据 hash 来选择 redis 连接, 这就需要 client 自己维护一个路由表对吗, 我想兼容 redis 协议,让使用的人直接用现有的 redis 的 client 来操作. |
16
ihuotui 2017-09-29 18:38:33 +08:00 via iPhone
没有代理服务,就是客户端维护 redis 路由咯
|
17
monsterxx03 2017-09-29 18:38:45 +08:00
加入节点的时候用的是类似 gossip protocol 的方式吧,如果用原生的 redis client, 如果初始连接的 node 挂了,就连不上整个集群了,实际上用的人要自己封装一下,从一个初始 list 中去做尝试
|
18
deadblock 2017-09-29 18:39:25 +08:00
已经 star,不谢
|
19
qiyue201707 OP @monsterxx03 是的 类似 gossip protocol
|
20
monsterxx03 2017-09-29 19:02:05 +08:00
这样还有个问题,hash 是 server 端完成然后做 forward 的,这和 elasticsearch 的集群模式是一样的。 用原生 client 的话,你的 request 压力瓶颈其实全在一台机器上,这样集群的意义不大。要实际使用,至少要和 elasticsearch 的 client 一样,实现一个从集群中拉取全部 node 信息的逻辑
|
21
EDDYCJY 2017-09-29 21:02:47 +08:00 via iPhone
差点以为楼主 95 年。。。
|
22
qiyue201707 OP |
23
JeffZ1993 2017-09-30 15:25:40 +08:00
感觉 groupcache 更能满足这种需求吧,兼容 redis 协议,也没什么特别的优势
|
24
qiyue201707 OP @monsterxx03 我想纠正一个问题,为什么这种模式请求压力会在同一个服务器上,P2P 模式完全分散了压力
|
25
monsterxx03 2017-10-09 13:24:51 +08:00
https://github.com/Leviathan1995/grape/blob/master/server/server.go#L116
因为是 server 端 hash 后, forward 请求,如果所有的客户端初始都连到一台 server 上,瓶颈当然就在这台机器上,当然你可以通过配置管理让不同的 client 初始连不同的 server,但这样实际上很麻烦,可用性很差的(比如你连的一台机器要下线了),不想动 client,基本就 twemproxy 那种代理模式最方便,坚持这种 server 端 forward 方式的话,要分散压力,必然要改 client 的, 做法会类似 elasticsearch 的 client https://github.com/elastic/elasticsearch-py/blob/master/elasticsearch/transport.py#L30 其实现在 redis 的分布式方案,可用的基本就 twemproxy, codis, redis cluster, 没动态扩容缩容需求 twemproxy 就够用. codis 要引入 zookeeper, redis cluster 那种 smart client 很多人不喜欢,基本都根据自家情况做 tradeoff |
26
qiyue201707 OP @monsterxx03 你说的这种问题在我看来无论什么样的模型都无法避免,在我看来,压力分流都要交给上层的业务自己去选择
|