项目正采用阿里的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)
就分享到这里吧, 如果有什么问题, 欢迎留言讨论