V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qiyue201707
V2EX  ›  程序员

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

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

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

    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   ·   实用小工具   ·   2684 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:21 · PVG 20:21 · LAX 04:21 · JFK 07:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.