官方文档
跨集群访问redis_cluster的问题是如何通过envoy解决的?
概览
代码细节
envoy基于nio网络编程,框架除了处理连接相关事宜外,业务都是扩展自各类事件的响应及回调
对于redis,envoy做了哪些扩展,先总体看下source/extensions
第一部分处理了cluster负载均衡相关实现,第二部分处理了命令协议、类型的封装编解码,客户端及事件封装等;第三部分提供了redis拦截入口,对命令的二次加工;
注册
source/extensions/filters/network/common/redis_proxy/config.cc
source/extensions/cluster/redis/redis_cluster.cc
负载均衡计算
通过实现Upstream::LoadBalancer的chooseHost被回调
chooseHost的具体实现在cc中,可以看到这里现实computeHashKey()得到hash再根据hash.value()%16384定位到具体的slot_array_
computeKey()就是返回了hash_key_,那么看下这个值怎么算出来
集群信息生成
选择算法看起来就是从slot_array_里按照rediscluster一样的策略搞一遍,再来看下集群节点是如何生成的
实现了Upstream::BaseDynamicClusterImpl,构造了redis命令CLUSTER SLOTS
通过回调,连接配置的集群信息,注册回调,发送请求
redis_cluster.cc中响应回调,当收到redis cluster slot命令响应之后,解析,存入cluster_slots且调用onClusterSlotUpdate通知
最终调用到redis_cluster_lb*,将信息更新到内存对象
命令处理
redis协议解码后, 经过filter处理命令
根据请求数据做对应的操作, 有些是直接在proxy拦截执行, 有些是请求redis返回结果, 有些在proxy再做一次聚合等