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

关于 redis 一个小问题(随机性)

  •  
  •   golangggg · 2023-07-23 01:31:36 +08:00 · 1899 次点击
    这是一个创建于 500 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题 想使用 redis 实现一个均匀使用 ip 的功能,
    自己有 10 个代理 ip, 想均匀的使用 ( 轮训着用 一个接着一个 循环往复)
    使用过两种方案
    1.ip 存为 set 类型 每次使用 srandmember 随机抽取, 但测试发现 非常不随机
    2.ip 存为 list 类型 每次 rpoplpush 到同一队列, 这个可以实现完全平均的使用,但有个问题无法解决, 因为可能某一个 ip 某短时间不可以使用, 需要从队列中移除, 但是使用 list 无法移除某一个失效的 ip
    想问下大佬们 有什么好的解决方案吗
    15 条回复    2023-07-24 11:18:19 +08:00
    zjp
        1
    zjp  
       2023-07-23 02:11:42 +08:00 via Android
    失效 IP 比例不高的话,可以方案二 + 再维护一个 set ,命中则再从 list 取一次
    mineralsalt
        2
    mineralsalt  
       2023-07-23 02:25:38 +08:00
    因为同一个 ip 可以同时执行很多请求, 如果用的时候从列表中移除,挺耽误效率的。
    mineralsalt
        3
    mineralsalt  
       2023-07-23 02:29:46 +08:00
    针对失效 ip 的问题我是这么解决的,分两块, 第一单独开一个线程定期扫描 ip 库添加可用的 ip 到 set 中。第二用的时候随机取, 但是需要封装统一 http 请求捕获异常,并且把请求超时时间设置的比较短。 当发生任何请求失败时从 redis set 中删除这个 ip , 这样基本上可以保证可用 ip 池都是新鲜可用的, 唯一的缺点就是失败的请求要重新取 ip 重试, 耽误几秒钟
    xuanbg
        4
    xuanbg  
       2023-07-23 07:33:52 +08:00
    zset 存 ip ,每次取 score 最小的,然后将这个 ip 的 score+1
    18870715400
        5
    18870715400  
       2023-07-23 10:11:35 +08:00
    好像可以使用一致性哈希算法来解决
    pastgift
        6
    pastgift  
       2023-07-23 12:17:47 +08:00
    list 也可以移除 ip 吧
    pastgift
        7
    pastgift  
       2023-07-23 12:18:00 +08:00
    127.0.0.1:6379> lpush test a
    (integer) 1
    127.0.0.1:6379> lpush test b
    (integer) 2
    127.0.0.1:6379> lpush test c
    (integer) 3
    127.0.0.1:6379> lrange test 0 -1
    1) "c"
    2) "b"
    3) "a"
    127.0.0.1:6379> lrem test 0 b
    (integer) 1
    127.0.0.1:6379> lrange test 0 -1
    1) "c"
    2) "a"
    127.0.0.1:6379>
    golangggg
        8
    golangggg  
    OP
       2023-07-23 13:19:31 +08:00
    @mineralsalt set 得问题方案 1 说到了, 非随机, 实际调用下来 多的跟少的能差一倍调用量, 另外 就是无法按照 12345678910 这个顺序 轮训使用 所以 不符合我的需求
    golangggg
        9
    golangggg  
    OP
       2023-07-23 13:20:24 +08:00
    @zjp 感觉是一个好方案, 其实不用 set 命中了应该按照 7 楼说的直接删除也行 我测一下
    golangggg
        10
    golangggg  
    OP
       2023-07-23 13:21:42 +08:00
    @xuanbg 用过这种方案, 并发不高的时候没问题,但是高并发的时候 做不到轮训的效果, 会导致某一个 ip 被连续取到多次
    golangggg
        11
    golangggg  
    OP
       2023-07-23 13:21:59 +08:00
    @pastgift 感觉像是正解 , 感谢 我测一下
    golangggg
        12
    golangggg  
    OP
       2023-07-23 13:22:32 +08:00
    @18870715400 我查一下, 触及到我的盲区了 哈哈
    mineralsalt
        13
    mineralsalt  
       2023-07-23 13:24:17 +08:00
    @golangggg #8 那说明你的 ip 池比较小吧, 我 100 多个 ip 感觉还行, 如果强行加锁给每个 ip 都设定权重,就会影响并发效率, 怎么取舍就看你了
    xuanbg
        14
    xuanbg  
       2023-07-23 13:48:33 +08:00
    @golangggg 并发你得加锁啊,不加锁任你什么方案都扯淡。
    happyxhw101
        15
    happyxhw101  
       2023-07-24 11:18:19 +08:00
    为什么不用 nginx 的 tcp 负载均衡
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1096 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 19:03 · PVG 03:03 · LAX 11:03 · JFK 14:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.