codis学习
一.codis-proxy 结构
- 1.Topology
- 2.Slots
- 3.ServerGroup
- 4.Server
二.codis-proxy 启动过程
1.初始化ProxyInfo
- Id
- Addr
- productName
2.Proxy 把自己标记成offline状态,将自己注册到zk上
- ProxyServer -> Topology -> Proxy -> CreateProxyInfo
- zk上的地址 /zk/codis/db_{productName}/proxy
3.Proxy 从zk上获取自己的状态
- 判断zk上的状态是online认为注册成功,并且开始监控zk自己的变化
- 如果还是offline状态,3秒以后重试,重新获取zk上的状态
4.监控子节点的状态
- zk上的地址 /zk/codis/db_{productName}/actions
5.初始化slots
- 每个codis-proxy有1024个slots
- 在zk上逐个获取slot
- 某一个slots在zk上的状态的path是/zk/codis/db_{productName}/slots/slot_{i}
- slot的状态,确保是online状态
- 在zk上逐个获取这个slot所在的server group
- 某一个server group在zk上的状态的path是/zk/codis/db_{productName}/servers/group_{i}
- 获取server group zk下的子节点列表
- 逐个在zk上获取server group下的server,并创建server对象
- 这样一个slot就是由 zk 上的slot zk上的server group(由server组成是一个一主多从的结构)组成
- 为了使用这个slot所以需要把server group中的那些servers中的主库创建连接
- 这里用slot的dst字段标示了slot所在主库的位置
- 同时在codis-proxy的redis连接池中添加这个主库的连接
- 这里需要说明一点的是,由于这个slot有可能处于migrate状态,在创建的时候同时记录了他是从哪个server group迁移过来的在migrateFrom字段,并且把迁移的主库添加到codis-proxy的连接池
6.开始事件循环
- 主要是处理之前监控的一些zk上的变更
7.监听codis-proxy的端口
- block
三.codis-proxy 的对外服务过程
- 对一个redis key的操作先把这个key crc32到某一个slot上
- 如果这个slot处于pre migrate需要阻塞对这个slot的操作
- 判断这个key是否处于migrate状态,如果是的话,在slot的migrateFrom的redis上执行一个迁移命令,命令的参数的slot的dst的IP和端口还有KEY的名字
- migrateFrom的这个redis会把key迁移到dst上并删除自己的key,所以migrateFrom是迁移中的那个老的实例,dst是迁移中的新实例
- 判断迁移命令的返回值,成功的话认为迁移成功
- 迁移成功以后,我们都是从dst这个新实例来读或者写这个key的内容返回给客户端
- 然后做的就是一个代理该做的事情了,写目标读写,结果返回给客户端
四.为什么codis要修改redis源码来支持迁移
- 一个原因是slot下的key set不好获得
- 一个原因就是redis的操作都是原子性的,如果在迁移的时候,是通过proxy的在老的上get,新的上set,这样没法保证其他proxy对这个key操作的原子性
一.codis-config 启动过程
- 解析productName zk地址
- 利用zk创建一个分布式锁 /zk/codis/db_{productName}/LOCK
- 关于利用zk创建分布式锁的方法有很多
- lock的时候可以在一个root下创建一个自增的临时节点,取root下的所有节点,自己是最小的认为获得锁,否则等待比自己小1的节点删除
- 因为zk保证里一致性,所以这个锁和单机操作系统中的信号量一样,取这个mutex的值,lock时候就减1,unlock时候加1
- 具体ocdis-config是用的哪种实现因为是在另一个项目里,所以还没看
- 在zk中创建配置 /zk/codis/db_{productName}/living-codis-config
- 一个defer 结束的时候删除之前zk创建的path
- 启动了一个监听在10086的HTTP管理后台
二.codis-config 命令
- 如果命令是阻塞的,会先获取之前的分布式锁,执行完以后会释放锁,只不过是一个一级命令一个锁
proxy命令
list命令,获取所有codis-proxy的代理信息
- 保存在zk的/zk/codis/db_{productName}/proxy 的子节点下
offline/online命令,将一个codis-proxy设置为下线和上线状态
- 先获取/zk/codis/db_{productName}/proxy/{proxyName}的proxy信息
- 如果是将proxy设置为上线状态,检查proxy下的所有slot是online状态
- 设置proxy状态是上线状态
- 如果是将proxy设置为下线状态,那么先设置proxy的状态为标记下线,也即是mark_offline
- 然后订阅节点的变更,直到他的状态为offline的时候认为下线成功
slot命令
migrate命令,迁移一个slot
- 从zk中获取所有slot的状态
- 检查集群中是否有正在迁移的slot,保证集群中同时只能有一个slot在迁移
- 迁移某个slot的时候先获取分布式锁,表示开始迁移某个slot,结束的时候释放
- 检查迁移到的server gorup可用
- 进入二阶段的提交的第一阶段,通知所有proxy 这个slot处于pre_migrate状态
- 等待所有proxy做出回复,修改slot状态为migrate状态,保存在zk上
- 在老的redis主库上执行slotsmgrtslot命令迁移slot到新的redis主库,直到slot中所有的key迁移完成
codis学习的更多相关文章
- codis+redis集群学习整理(待续)
Codis 由四部分组成: Codis Proxy (codis-proxy) Codis Manager (codis-config) Codis Redis (codis-server) ZooK ...
- codis集群安装
在网上找了很多codis的集群安装方法,看起来都是大同小异,本人结合了大多种方法完成了一套自己使用的codis的集群安装,可以供大家学习使用,如果有什么问题或者不懂的地方欢迎指正 1.集群规划: 三台 ...
- Codis集群的搭建与使用
一.简介 Codis是一个分布式的Redis解决方案,对于上层的应用来说,连接Codis Proxy和连接原生的Redis Server没有明显的区别(不支持的命令列表),上层应用可以像使用单机的Re ...
- Codis集群的搭建
Codis集群的搭建与使用 一.简介 Codis是一个分布式的Redis解决方案,对于上层的应用来说,连接Codis Proxy和连接原生的Redis Server没有明显的区别(不支持的命令列表 ...
- 互联网世界中的C语言——我的golang学习笔记:1(基础语法快速过)
前言 学习任何知识都会有一个学习背景 最近,我们团队乃至我司整个云服务,上go的呼声越来越高!新服务已经开始用go开发,部分现有Java版的服务重构为go也只是时间问题而已,故相关技术积累势在必行!在 ...
- 豌豆夹Redis解决方式Codis源代码剖析:Proxy代理
豌豆夹Redis解决方式Codis源代码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描写叙述: Codis is a proxy b ...
- 豌豆夹Redis解决方案Codis源码剖析:Proxy代理
豌豆夹Redis解决方案Codis源码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描述: Codis is a proxy base ...
- Java工程师学习指南 完结篇
Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校 ...
- [Big Data - Codis] Codis集群的搭建与使用
一.简介 Codis是一个分布式的Redis解决方案,对于上层的应用来说,连接Codis Proxy和连接原生的Redis Server没有明显的区别(不支持的命令列表),上层应用可以像使用单机的Re ...
随机推荐
- poj1862
一.题意:两个物体m1.m2相撞后会变成一个物体,这个物体的重量会变成2*sqrt(m1*m2).有n个物体,假设只会发生两两相撞,求最后剩下的最小重量. 二.思路:简单的贪心.越大的数开越多的次方, ...
- PIE SDK均值滤波
1.算法功能简介 均值滤波是最常用的线性低通滤波,它均等地对待邻域中的每个像素.对于每个像素,取邻域像素值的平均作为该像素的新值.均值滤波算法简单,计算速度快,对高斯噪声比较有效.从频率域的角度看,相 ...
- python-OS.path.join()路径拼接
os.path.join()函数: 第一个以”/”开头的参数开始拼接,之前的参数全部丢弃. 以上一种情况为先.在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼 ...
- 8086实时时钟实验(二)——《x86汇编语言:从实模式到保护模式》读书笔记06
上次我们说了代码,这次我们说说怎样看到实验结果. 首先编译源文件(我的源文件就在当前路径下,a盘和c盘在上一级目录下): nasm -f bin c08_mbr.asm -o c08_mbr.bin ...
- 移动平台的meta标签(转)
1.Meta 之 viewport 说到移动平台meta标签,那就不得不说一下viewport了,那么什么是viewport呢? viewport即可视区域,对于桌面浏览器而言,viewport指的就 ...
- spring开发中commons-logging.jar包的功能
删除后程序会报错 Java.lang.NoClassDefFoundError 记录日志,通常和 log4j.jar共同使用 原因: 在 sun 开发 logger 前,apache 项目已经开发了 ...
- FZU 2213——Common Tangents——————【两个圆的切线个数】
Problem 2213 Common Tangents Accept: 7 Submit: 8Time Limit: 1000 mSec Memory Limit : 32768 KB ...
- 自己动手实现STL 01:内存配置器的实现(stl_alloc.h)
一.前言 在STL中,容器是其中的重中之重,基本的STL中的算法,仿函数等都是围绕着容器实现的功能.而,内存配置器,是容器的实现的基础.所以,我第一次要去编写便是内存配置器的实现.在STL中,内存配置 ...
- css之margin,padding的百分比
注意:上下内边距与左右内边距一致:即上下内边距的百分数会相对于父元素宽度设置,而不是相对于高度. PS:而且是基于父元素内容的宽度(width属性的大小),不是基于父元素整个框架的宽度
- The nineteenth day
Twinkle,twinkle,little start! 闪烁,闪烁,小星星 How I wonder what you are, 我想知道你是什么 Up above the world so hi ...