Redis的key竞争问题 一个简单的解决方案

项目正采用阿里的canal开源项目作为mysql和redis的数据一致性方案, 当Canal client从Canal Server消费数据时, canal保证了时序, 但是在client端写入Redis时, 发现单连接顺序执行的效率不够, 会影响整体消费速率.那么就需要多协程多连接并发写,这样就会存在key的竞争问题.

首先想到的是加锁的方案, 单机情况, 对一个key进行redis写入操作时, 先获取key的锁, 然后执行, 多个redis连接协程同时执行时,这样也无法完全避免时序问题,还需要加时间戳, 还存在阻塞等待问题, 分布式的情况下,更麻烦, 通常还要考虑第三方工具...

最后经过思索,想到一个多协程分组解决方案, 即获取key的hash值, 然后以此分组, 保证每个key都会分配到同一个协程去执行, 这样就解决了key的竞争问题

// 生成hash code
func (s *CanalService) getHashCode(str string) (uint32) {
	s.hs.Write([]byte(str))
	hcode := s.hs.Sum32()
	s.hs.Reset()
	return hcode
}

// 写入对应协程的缓存区
hCode := s.getHashCode(key)
s.dataCache[int(hCode%uint32(s.redisRoutinesNum))] <- row

// 每个协程取自己的缓存区的数据进行操作
data := <- s.dataCache[routineIdx]:
s.processRowData(data)

就分享到这里吧, 如果有什么问题, 欢迎留言讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值