关于作者
钟 悦 - 资深DBLE用户
某宇宙行资深架构师,在大型重点项目中使用 DBLE。
常年与 MySQL 纠缠不清,经常运用技术处理大企业病的技术or非技术问题的一个挨踢从业者。
以每24小时作为一份时间(而非自然日),根据用户的配置有两种工作模式:带状模式中,用户仅定义开始日期时,从开始日期(含)开始,每份时间1个分片地无限增加下去;环状模式中,用户定义了开始日期和结束日期时,以结束日期(含)和开始日期(含)之间的时间份数作为分片总数(分片数量固定),以类似取模的方式路由到这些分片里。
- DBLE 启动时,读取用户在 rule.xml 配置的 sBeginDate 来确定起始时间
- 读取用户在 rule.xml 配置的 sPartionDay 来确定每个 MySQL 分片承载多少天内的数据
- 读取用户在 rule.xml 配置的 dateFormat 来确定分片索引的日期格式
- 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的时间类型
- 然后求分片索引值与起始时间的差,除以 MySQL 分片承载的天数,确定所属分片
- DBLE 启动时,读取用户在 rule.xml 配置的起始时间 sBeginDate、终止时间 sEndDate 和每个 MySQL 分片承载多少天数据 sPartionDay
- 根据用户设置,建立起以 sBeginDate 开始,每 sPartionDay 天一个分片,直到 sEndDate 为止的一个环,把分片串联串联起来
- 读取用户在 rule.xml 配置的 defaultNode
- 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的日期类型
- 然后求分片索引值与起始日期的差:如果分片索引值不早于 sBeginDate(哪怕晚于 sEndDate),就以 MySQL 分片承载的天数为模数,对分片索引值求模得到所属分片;如果分片索引值早于 sBeginDate,就会被放到 defaultNode 分片上
与MyCat的类似分片算法对比
中间件 | DBLE | MyCat |
分片算法种类 | date 分区算法 | 按日期(天)分片 |
- 两种中间件的取模范围分片算法使用上无差别
开发注意点
- 【分片索引】1. 必须是字符串,而且 java.text.SimpleDateFormat 能基于用户指定的 dateFormat 来转换成 java.util.Date
- 【分片索引】2. 提供带状模式和环状模式两种模式
- 【分片索引】3. 带状模式以 sBeginDate(含)起,以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,理论上分片数量可以无限增长,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)
- 【分片索引】4. 环状模式以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,以 sBeginDate(含)到 sEndDate(含)的时间长度除以单个分片长度得到恒定的分片数量,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)
- 【分片索引】5. 无论哪种模式,分片索引字段的格式化字符串 dateFormat 由用户指定
- 【分片索引】6. 无论哪种模式,划分不是以日历时间为准,无法对应自然月和自然年,且会受闰秒问题影响
运维注意点
- 【扩容】1,带状模式中,随着 sBeginDate 之后的数据出现,分片数量的增加无需再平衡
- 【扩容】2,带状模式没有自动增添分片的能力,需要运维手工提前增加分片;如果路由策略计算出的分片并不存在时,会导致失败
- 【扩容】3,环状模式中,如果新旧 [sBeginDate,sEndDate] 之间有重叠,需要进行部分数据迁移;如果新旧 [sBeginDate,sEndDate] 之间没有重叠,需要数据再平衡
配置注意点
- 【配置项】1,在 rule.xml 中,可配置项为
<property name="sBeginDate">
、<property name="sPartionDay">
、<property name="dateFormat">
、<property name="sEndDate">
和 <property name="defaultNode">
- 【配置项】2,在 rule.xml 中配置
<property name="dateFormat">
,符合 java.text.SimpleDateFormat 规范的字符串,用于告知 DBLE 如何解析sBeginDate和sEndDate - 【配置项】3,在 rule.xml 中配置
<property name="sBeginDate">
,必须是符合 dateFormat 的日期字符串 - 【配置项】4,在 rule.xml 中配置
<property name="sEndDate">
,必须是符合 dateFormat 的日期字符串;配置了该项使用的是环状模式,若没有配置该项则使用的是带状模式 - 【配置项】5,在 rule.xml 中配置
<property name="sPartionDay">
,非负整数,该分片策略以 86400000 毫秒(24 小时整)作为一份,而 sPartionDay 告诉 DBLE 把每多少份放在同一个分片 - 【配置项】6,在 rule.xml 中配置
<property name="defaultNode">
标签,非必须配置项,不配置该项的话,用户的分片索引值没落在 mapFile 定义的范围时,DBLE 会报错;若需要配置,必须为非负整数,用户的分片索引值没落在 mapFile 定义的范围时,DBLE 会路由至这个值的 MySQL 分片