自己写的分布式缓存,求轻拍 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
qiyue201707
V2EX    程序员

自己写的分布式缓存,求轻拍

  •  3
     
  •   qiyue201707 2017-09-29 15:00:23 +08:00 4736 次点击
    这是一个创建于 2937 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近写的一个分布式缓存, 感兴趣的可以

    https://github.com/Leviathan1995/grape

    兼容 Redis 协议, 因为 Redis 协议数据表现力很强, 但是集群的使用需要主从模式,所以考虑写一个完全 P2P 结构的分布式缓存, 通过一致性哈希分散数据, 使用客户端连接集群里任意节点就能进行服务,使用redis_cli新增节点和删除节点都特别简单.

    TODO

    目前支持的命令只有 SET,GET,后面慢慢加.

    TTL

    因为没有 master 的概念, 现在最主要的就是考虑如何实现节点的存活检测, 考虑要不要也像 Redis 加入哨兵机制,这个问题欢迎大家一起讨论...

    26 条回复    2017-10-09 13:35:28 +08:00
    NullMan
        1
    NullMan  
       2017-09-29 15:40:33 +08:00
    问个问题,用 redis_cli 删除一节点后,这被删除的节点的数据怎么个处理了?
    qiyue201707
        2
    qiyue201707  
    OP
       2017-09-29 15:44:34 +08:00
    @NullMan 目前的情况是数据就没有了,但这个问题后面我会改成集群里存在备份节点,删除一个节点后,更新整个集群里所有的节点的路由表,之后每次的服务就移动到备份节点了, 因为是缓存,我觉得数据是允许丢失的
    NullMan
        3
    NullMan  
       2017-09-29 16:48:30 +08:00
    @qiyue201707 我认为删除就是删除了,既然要删除一个节点,就说明已经容许数据丢失,就如你说的 “因为是缓存,我觉得数据是允许丢失的。”

    当然,这是设计上的问题,主要看你怎么定义 “删除节点”。
    qiyue201707
        4
    qiyue201707  
    OP
       2017-09-29 16:50:02 +08:00
    @NullMan 删除节点也有可能节点不可用了
    Allianzcortex
        5
    Allianzcortex  
       2017-09-29 16:52:26 +08:00 via iPhone
    LZ 在 infra 方向真是我辈楷模啊
    qiyue201707
        6
    qiyue201707  
    OP
       2017-09-29 16:55:04 +08:00
    @Allianzcortex 楷模谈不上....本身就是个基础架构方向的新兵,现在还在学习阶段....
    Allianzcortex
        7
    Allianzcortex  
       2017-09-29 17:03:03 +08:00
    @qiyue201707 太谦虚了......新建了一个 V2 账号吗?
    Allianzcortex
        8
    Allianzcortex  
       2017-09-29 17:03:36 +08:00
    @NullMan @qiyue201707 我是觉得缓存这类本身的特性决定了要选择 C 而非 A,就算是穿透了也有后面的数据库兜底 /(ㄒoㄒ)/~~emmmmmm
    qiyue201707
        9
    qiyue201707  
    OP
       2017-09-29 17:07:56 +08:00
    @Allianzcortex 是换了一个账号,不想暴露太多个人信息...
    关于是否添加备份节点可以通过配置项让使用者自己决定,尽可能的提高容灾
    neoblackcap
        10
    neoblackcap  
       2017-09-29 17:22:29 +08:00
    我想问一下使用问题
    1. 是不是我连接的时候还是需要指定节点的 ip ?
    2. 节点挂了是不是要自己重新连接?

    还有就是这个缓存的数据一致性是怎么样?
    qiyue201707
        11
    qiyue201707  
    OP
       2017-09-29 17:26:18 +08:00
    @neoblackcap 连接的时候指定集群中任意节点就行了, 节点挂了重启自动重新连接

    数据没有一致性, 每个节点只存一份数据.
    Allianzcortex
        12
    Allianzcortex  
       2017-09-29 17:44:07 +08:00
    @neoblackcap 这个版本是 decentralized,所以没有类似 paxos/raft 的 master/slave 选主,所以数据只有 0 和 1 两种状态,是吧 @qiyue201707
    qiyue201707
        13
    qiyue201707  
    OP
       2017-09-29 17:49:07 +08:00
    movistar
        14
    movistar  
       2017-09-29 17:49:46 +08:00
    实际上就是对 key 做数据一致性哈希分桶?
    存储节点互相独立,互不影响么
    一般来说分布式服务都需要一个 meta server 吧,或者 name server
    如何避免一台服务器宕机后导致的内存穿透问题呢
    如果只是简单的做了分桶,为啥不直接在 client 侧根据 hash 结果选择不同 redis 连接呢
    redis 还有主备,能保证一个节点宕机另一个可用
    qiyue201707
        15
    qiyue201707  
    OP
       2017-09-29 18:03:52 +08:00
    @movistar 缓存穿透问题加备份节点就能尽可能解决
    client 根据 hash 来选择 redis 连接, 这就需要 client 自己维护一个路由表对吗, 我想兼容 redis 协议,让使用的人直接用现有的 redis 的 client 来操作.
    ihuotui
        16
    ihuotui  
       2017-09-29 18:38:33 +08:00 via iPhone
    没有代理服务,就是客户端维护 redis 路由咯
    monsterxx03
        17
    monsterxx03  
       2017-09-29 18:38:45 +08:00
    加入节点的时候用的是类似 gossip protocol 的方式吧,如果用原生的 redis client, 如果初始连接的 node 挂了,就连不上整个集群了,实际上用的人要自己封装一下,从一个初始 list 中去做尝试
    deadblock
        18
    deadblock  
       2017-09-29 18:39:25 +08:00
    已经 star,不谢
    qiyue201707
        19
    qiyue201707  
    OP
       2017-09-29 18:40:16 +08:00
    @monsterxx03 是的 类似 gossip protocol
    monsterxx03
        20
    monsterxx03  
       2017-09-29 19:02:05 +08:00
    这样还有个问题,hash 是 server 端完成然后做 forward 的,这和 elasticsearch 的集群模式是一样的。 用原生 client 的话,你的 request 压力瓶颈其实全在一台机器上,这样集群的意义不大。要实际使用,至少要和 elasticsearch 的 client 一样,实现一个从集群中拉取全部 node 信息的逻辑
    EDDYCJY
        21
    EDDYCJY  
       2017-09-29 21:02:47 +08:00 via iPhone
    差点以为楼主 95 年。。。
    qiyue201707
        22
    qiyue201707  
    OP
       2017-09-29 21:23:12 +08:00
    @monsterxx03 是 单机的瓶颈需要考虑
    @EDDYCJY
    JeffZ1993
        23
    JeffZ1993  
       2017-09-30 15:25:40 +08:00
    感觉 groupcache 更能满足这种需求吧,兼容 redis 协议,也没什么特别的优势
    qiyue201707
        24
    qiyue201707  
    OP
       2017-10-09 11:41:13 +08:00
    @monsterxx03 我想纠正一个问题,为什么这种模式请求压力会在同一个服务器上,P2P 模式完全分散了压力
    monsterxx03
        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
    qiyue201707
        26
    qiyue201707  
    OP
       2017-10-09 13:35:28 +08:00
    @monsterxx03 你说的这种问题在我看来无论什么样的模型都无法避免,在我看来,压力分流都要交给上层的业务自己去选择
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5354 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 08:58 PVG 16:58 LAX 01:58 JFK 04:58
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86