共计 3854 个字符,预计需要花费 10 分钟才能阅读完成。
导览
本大节介绍数据分片局部的其余性能,次要包含:
- Inline 表达式
- 分布式主键
- 强制分片路由
行表达式
- 实现动机
- 语法阐明
- 配置数据节点
- 配置分片算法
实现动机
配置的简化与一体化是行表达式所心愿解决的两个次要问题。
在繁琐的数据分片规定配置中,随着数据节点的增多,大量的反复配置使得配置自身不易被保护。通过行表达式能够无效的简化数据节点配置工作量。
对于常见的分片算法,应用 Java 代码实现并不有助于配置的对立治理。通过行表达式书写分片算法,能够无效的将规定配置一起寄存,更加易于浏览与存储。
语法阐明
行表达式的应用十分直观,只须要在配置中应用 ${expression} 或 $->{expression} 标识行表达式即可。目前反对数据节点和分片算法这两个局部的配置。行表达式的内容应用的是 Groovy 的语法,Groovy 可能反对的所有操作,行表达式均可能反对。例如:
${begin..end} 示意范畴区间
${[unit1, unit2, unit_x]} 示意枚举值
行表达式中如果呈现间断多个 ${expression} 或 $->{expression} 表达式,整个表达式最终的后果将会依据每个子表达式的后果进行笛卡尔组合。
例如,以下行表达式:
${['online', 'offline']}_table${1..3}
最终会解析为:
online_table1, online_table2, online_table3, offline_table1, offline_table2, offline_table3
配置数据节点
对于均匀分布的数据节点,如果数据结构如下:
db0 ├── t_order0 └── t_order1 db1 ├── t_order0 └── t_order1
用行表达式能够简化为:
db${0..1}.t_order${0..1}
或者
db$->{0..1}.t_order$->{0..1}
对于自定义的数据节点,如果数据结构如下:
db0 ├── t_order0 └── t_order1 db1 ├── t_order2 ├── t_order3 └── t_order4
用行表达式能够简化为:
db0.t_order${0..1},db1.t_order${2..4}
或者
db0.t_order$->{0..1},db1.t_order$->{2..4}
对于有前缀的数据节点,也能够通过行表达式灵便配置,如果数据结构如下:
db0 ├── t_order_00 ├── t_order_01 ├── t_order_02 ├── t_order_03 ├── t_order_04 ├── t_order_05 ├── t_order_06 ├── t_order_07 ├── t_order_08 ├── t_order_09 ├── t_order_10 ├── t_order_11 ├── t_order_12 ├── t_order_13 ├── t_order_14 ├── t_order_15 ├── t_order_16 ├── t_order_17 ├── t_order_18 ├── t_order_19 └── t_order_20db1 ├── t_order_00 ├── t_order_01 ├── t_order_02 ├── t_order_03 ├── t_order_04 ├── t_order_05 ├── t_order_06 ├── t_order_07 ├── t_order_08 ├── t_order_09 ├── t_order_10 ├── t_order_11 ├── t_order_12 ├── t_order_13 ├── t_order_14 ├── t_order_15 ├── t_order_16 ├── t_order_17 ├── t_order_18 ├── t_order_19 └── t_order_20
能够应用离开配置的形式,先配置蕴含前缀的数据节点,再配置不含前缀的数据节点,再利用行表达式笛卡尔积的个性,主动组合即可。下面的示例,用行表达式能够简化为:
db${0..1}.t_order_0${0..9}, db${0..1}.t_order_${10..20}
或者
db->${0..1}.t_order_0$->{0..9}, db$->{0..1}.t_order_$->{10..20}
配置分片算法
对于只有一个分片键的应用 = 和 IN 进行分片的 SQL,能够应用行表达式代替编码方式配置。
行表达式外部的表达式实质上是一段 Groovy 代码,能够依据分片键进行计算的形式,返回相应的实在数据源或实在表名称。
例如:分为 10 个库,尾数为 0 的路由到后缀为 0 的数据源,尾数为 1 的路由到后缀为 1 的数据源,以此类推。用于示意分片算法的行表达式为:
ds${id % 10}
或者
ds$->{id % 10}
分布式主键
实现动机
传统数据库软件开发中,主键主动生成技术是根本需要。而各个数据库对于该需要也提供了相应的反对,比方 MySQL 的自增键,Oracle 的自增序列等。数据分片后,不同数据节点生成全局惟一主键是十分辣手的问题。同一个逻辑表内的不同理论表之间的自增键因为无奈相互感知而产生反复主键。尽管可通过束缚自增主键初始值和步长的形式防止碰撞,但需引入额定的运维规定,使解决方案不足完整性和可扩展性。
目前有许多第三方解决方案能够完满解决这个问题,如 UUID 等依附特定算法自生成不反复键,或者通过引入主键生成服务等。为了不便用户应用、满足不同用户不同应用场景的需要,ShardingSphere 不仅提供了内置的分布式主键生成器,例如 UUID、SNOWFLAKE,还抽离出分布式主键生成器的接口,不便用户自行实现自定义的自增主键生成器。
内置的主键生成器
UUID
采纳 UUID.randomUUID() 的形式产生分布式主键。
SNOWFLAKE
ShardingSphere 提供灵便的配置分布式主键生成策略形式。在分片规定配置模块可配置每个表的主键生成策略,默认应用雪花算法(snowflake)生成 64bit 的长整型数据。
雪花算法是由 Twitter 颁布的分布式主键生成算法,它可能保障不同过程主键的不重复性,以及雷同过程主键的有序性。
在同一个过程中,它首先是通过工夫位保障不反复,如果工夫雷同则是通过序列位保障。同时因为工夫位是枯燥递增的,且各个服务器如果大体做了工夫同步,那么生成的主键在分布式环境能够认为是总体有序的,这就保障了对索引字段的插入的高效性。例如 MySQL 的 Innodb 存储引擎的主键。
应用雪花算法生成的主键,二进制示意模式蕴含 4 局部,从高位到低位分表为:1bit 符号位、41bit 工夫戳位、10bit 工作过程位以及 12bit 序列号位。
- 符号位 (1bit)
预留的符号位,恒为零。
- 工夫戳位 (41bit)
41 位的工夫戳能够包容的毫秒数是 2 的 41 次幂,一年所应用的毫秒数是:365 * 24 * 60 * 60 * 1000。通过计算可知:
Math.pow(2, 41) / (365 * 24 * 60 * 60 * 1000L);
后果约等于 69.73 年。ShardingSphere 的雪花算法的工夫纪元从 2016 年 11 月 1 日零点开始,能够应用到 2086 年,置信能满足绝大部分零碎的要求。
- 工作过程位 (10bit)
该标记在 Java 过程内是惟一的,如果是分布式应用部署应保障每个工作过程的 id 是不同的。该值默认为 0,可通过属性设置。
- 序列号位 (12bit)
该序列是用来在同一个毫秒内生成不同的 ID。如果在这个毫秒内生成的数量超过 4096(2 的 12 次幂),那么生成器会期待到下个毫秒持续生成。
时钟回拨
服务器时钟回拨会导致产生反复序列,因而默认分布式主键生成器提供了一个最大容忍的时钟回拨毫秒数。如果时钟回拨的工夫超过最大容忍的毫秒数阈值,则程序报错;如果在可容忍的范畴内,默认分布式主键生成器会期待时钟同步到最初一次主键生成的工夫后再持续工作。最大容忍的时钟回拨毫秒数的默认值为 0,可通过属性设置。
雪花算法主键的具体构造见下图。
LEAF
在 5.0.0 版本之前,借鉴 Leaf,次要分为 Leaf-segment 和 Leaf-snowflake 两种计划。ShardingSphere 在 4.0.0-RC2-release 版本中实现了 Leaf-segment,在 4.0.0-RC3-release 版本中实现了 Leaf-snowflake。
从 5.0.0 版本起,以上两个实现从 ShardingSphere 中移除。咱们从新适配了第三方的 Leaf 开源实现,并挪动到 OpenSharding 仓库中。具体应用形式,请参考 OpenSharding/sharding-keygen-leaf 我的项目。
强制分片路由
- 实现动机
- 实现机制
实现动机
通过解析 SQL 语句提取分片键列与值并进行分片是 ShardingSphere 对 SQL 零侵入的实现形式。若 SQL 语句中没有分片条件,则无奈进行分片,须要全路由。
在一些利用场景中,分片条件并不存在于 SQL,而存在于内部业务逻辑。因而须要提供一种通过内部指定分片后果的形式,在 ShardingSphere 中叫做 Hint。
实现机制
ShardingSphere 应用 ThreadLocal 治理分片键值。能够通过编程的形式向 HintManager 中增加分片条件,该分片条件仅在以后线程内失效。
除了通过编程的形式应用强制分片路由,ShardingSphere 还打算通过 SQL 中的非凡正文的形式援用 Hint,使开发者能够采纳更加通明的形式应用该性能。
指定了强制分片路由的 SQL 将会忽视原有的分片逻辑,间接路由至指定的实在数据节点。