Apache ShardingSphere 5.0.0 内核优化及升级指南
经过近两年时间的优化和打磨,Apache ShardingSphere 5.0.0 GA 版终于在本月正式发布,相比于 4.1.1 GA 版,5.0.0 GA 版在内核层面进行了大量的优化。首先,基于可插拔架构对内核进行了全面改造,内核中的各个功能可以任意组合并叠加使用。其次,为了提升 SQL 分布式查询能力,5.0.0 GA 版打造了全新的Federation 执行引擎,来满足用户复杂的业务场景。此外,5.0.0 GA 版在内核功能 API 层面也进行了大量优化,旨在降低用户使用这些功能的成本。本文将为大家详细解读 5.0.0 GA 版中的这些重大内核优化,并将对比两个 GA 版本中存在的差异,以典型的数据分片、读写分离和加解密整合使用的场景为例,帮助用户更好地理解这些优化并完成版本升级。
端正强
可拔插架构内核

- 数据分片:实现了元数据加载、SQL 路由、SQL 改写和结果归并的全部功能扩展点,在数据分片功能内部,又提供了分片算法、分布式 ID 等扩展点;
- 读写分离:实现了 SQL 路由的功能扩展点,功能内部提供了负载均衡算法扩展点;
- 加解密:实现了元数据加载、SQL 改写和结果归并的扩展点,内部提供了加解密算法扩展点;
- 影子库压测:实现了 SQL 路由的扩展点,在影子库压测功能内部,提供了影子算法扩展点;
- 高可用:实现了 SQL 路由的扩展点。
|
版本
|
4.1.1 GA
|
5.0.0 GA
|
|
定位
|
分库分表中间件
|
分布式数据库生态系统
|
|
功能
|
提供基础功能
|
提供基础设施和最佳实践
|
|
耦合
|
耦合较大,存在功能依赖
|
相互隔离,互无感知
|
|
组合使用
|
固定的组合方式,必须以数据分片为基础,叠加读写分离和加解密等功能
|
功能自由组合,数据分片、读写分离、影子库压测、加解密和高可用等功能可以任意叠加组合
|
Federation 执行引擎

- 跨库关联查询:当关联查询中的多个表分布在不同的数据库实例上时,由 Federation 执行引擎提供支持。
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_inline
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_item_inline
SELECT * FROM t_order o INNER JOIN t_order_item i ON o.order_id = i.order_id WHERE o.order_id = 1;
SELECT * FROM t_order o INNER JOIN t_user u ON o.user_id = u.user_id WHERE o.user_id = 1;
SELECT * FROM t_order o LEFT JOIN t_user_role r ON o.user_id = r.user_id WHERE o.user_id = 1;
SELECT * FROM t_order_item i LEFT JOIN t_user u ON i.user_id = u.user_id WHERE i.user_id = 1;
SELECT * FROM t_order_item i RIGHT JOIN t_user_role r ON i.user_id = r.user_id WHERE i.user_id = 1;
SELECT * FROM t_user u RIGHT JOIN t_user_role r ON u.user_id = r.user_id WHERE u.user_id = 1;
- 子查询:Apache ShardingSphere 的 Simple Push Down 引擎能够支持分片条件一致的子查询,以及路由到单个分片的子查询。对于子查询和外层查询未同时指定分片键,或分片键的值不一致的场景,需要由 Federation 执行引擎来提供支持。
SELECT * FROM t_order o INNER JOIN t_order_item i ON o.order_id = i.order_id WHERE o.order_id = 1;
SELECT * FROM t_order o INNER JOIN t_user u ON o.user_id = u.user_id WHERE o.user_id = 1;
SELECT * FROM t_order o LEFT JOIN t_user_role r ON o.user_id = r.user_id WHERE o.user_id = 1;
SELECT * FROM t_order_item i LEFT JOIN t_user u ON i.user_id = u.user_id WHERE i.user_id = 1;
SELECT * FROM t_order_item i RIGHT JOIN t_user_role r ON i.user_id = r.user_id WHERE i.user_id = 1;
SELECT * FROM t_user u RIGHT JOIN t_user_role r ON u.user_id = r.user_id WHERE u.user_id = 1;
- 聚合查询:对于 Apache ShardingSphere Simple Push Down 引擎暂不支持的一些聚合查询,我们也同样通过 Federation 执行引擎提供了支持。
SELECT user_id, SUM(order_id) FROM t_order GROUP BY user_id HAVING SUM(order_id) > 10;
SELECT (SELECT MAX(user_id) FROM t_order) a, order_id FROM t_order;
SELECT COUNT(DISTINCT user_id), SUM(order_id) FROM t_order;
内核功能 API 调整
数据分片 API 调整
shardingRule:
tables:
t_order:
databaseStrategy:
standard:
shardingColumn: order_id
preciseAlgorithmClassName: xxx
rangeAlgorithmClassName: xxx
complex:
shardingColumns: year, month
algorithmClassName: xxx
hint:
algorithmClassName: xxx
inline:
shardingColumn: order_id
algorithmExpression: ds_${order_id % 2}
none:
tableStrategy:
...
rules:
- !SHARDING
tables:
t_order:
databaseStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: database_inline
complex:
shardingColumns: year, month
shardingAlgorithmName: database_complex
hint:
shardingAlgorithmName: database_hint
none:
tableStrategy:
... shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds_${order_id % 2}
database_complex:
type: CLASS_BASED
props:
strategy: COMPLEX
algorithmClassName: xxx
database_hint:
type: CLASS_BASED
props:
strategy: HINT
algorithmClassName: xxx
rules:
- !SHARDING
autoTables:
# 自动分片策略
t_order:
actualDataSources: ds_0, ds_1
shardingStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: auto_mod
keyGenerateStrategy:
column: order_id
keyGeneratorName: snowflake
shardingAlgorithms:
auto_mod:
type: MOD
props:
sharding-count: 4 tables:
# 手动声明分片策略
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: table_inline
dataBaseStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: database_inline
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingAlgorithmName: table_inline
defaultShardingColumn: order_id
defaultDatabaseStrategy:
standard:
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
读写分离 API 调整
# 4.1.1 GA 读写分离 API
masterSlaveRule:
name: ms_ds
masterDataSourceName: master_ds
slaveDataSourceNames:
- slave_ds_0
- slave_ds_1 # 5.0.0 GA 读写分离 API
rules:
- !READWRITE_SPLITTING
dataSources:
pr_ds:
writeDataSourceName: write_ds
readDataSourceNames:
- read_ds_0
- read_ds_1
加解密 API 调整
rules:
- !ENCRYPT
encryptors:
aes_encryptor:
type: AES
props:
aes-key-value: 123456abc
md5_encryptor:
type: MD5
tables:
t_encrypt:
columns:
user_id:
plainColumn: user_plain
cipherColumn: user_cipher
encryptorName: aes_encryptor
order_id:
cipherColumn: order_cipher
encryptorName: md5_encryptor
queryWithCipherColumn: true
queryWithCipherColumn: false
影子库压测 API 调整
shadowRule:
column: shadow
shadowMappings:
ds: shadow_ds
rules:
- !SHADOW
enable: true
dataSources:
shadowDataSource:
sourceDataSourceName: ds
shadowDataSourceName: shadow_ds
tables:
t_order:
dataSourceNames:
- shadowDataSource
shadowAlgorithmNames:
- user-id-insert-match-algorithm
- simple-hint-algorithm
shadowAlgorithms:
user-id-insert-match-algorithm:
type: COLUMN_REGEX_MATCH
props:
operation: insert
column: user_id
regex: "[1]"
simple-hint-algorithm:
type: SIMPLE_NOTE
props:
shadow: true
foo: bar
5.0.0 GA 升级指南
shardingRule:
tables:
t_order:
actualDataNodes: ms_ds_${0..1}.t_order_${0..1}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_${order_id % 2}
t_order_item:
actualDataNodes: ms_ds_${0..1}.t_order_item_${0..1}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_item_${order_id % 2}
bindingTables:
- t_order,t_order_item
broadcastTables:
- t_config
defaultDataSourceName: ds_0
defaultDatabaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ms_ds_${user_id % 2}
defaultTableStrategy:
none: masterSlaveRules:
ms_ds_0:
masterDataSourceName: ds_0
slaveDataSourceNames:
- ds_0_slave_0
- ds_0_slave_1
loadBalanceAlgorithmType: ROUND_ROBIN
ms_ds_1:
masterDataSourceName: ds_1
slaveDataSourceNames:
- ds_1_slave_0
- ds_1_slave_1
loadBalanceAlgorithmType: ROUND_ROBIN encryptRule:
encryptors:
aes_encryptor:
type: aes
props:
aes.key.value: 123456abc
tables:
t_order:
columns:
content:
plainColumn: content_plain
cipherColumn: content_cipher
encryptor: aes_encryptor
t_user:
columns:
telephone:
plainColumn: telephone_plain
cipherColumn: telephone_cipher
encryptor: aes_encryptor
CREATE TABLE t_order(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100));
# Logic SQL: CREATE TABLE t_order(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100)) CREATE TABLE t_order_item(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100));
# Logic SQL: CREATE TABLE t_order_item(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_item_0(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_item_1(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_item_0(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_item_1(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100)) CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone VARCHAR(100));
# Logic SQL: CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone VARCHAR(100))
# ds_0 创建 t_order_0、t_order_1 和 t_user
CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content_plain VARCHAR(100), content_cipher VARCHAR(100))
CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content_plain VARCHAR(100), content_cipher VARCHAR(100))
CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone_plain VARCHAR(100), telephone_cipher VARCHAR(100)) # ds_1 创建 t_order_0 和 t_order_1
CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content_plain VARCHAR(100), content_cipher VARCHAR(100))
CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content_plain VARCHAR(100), content_cipher VARCHAR(100))
INSERT INTO t_order(order_id, user_id, content) VALUES(1, 1, 'TEST11'), (2, 2, 'TEST22'), (3, 3, 'TEST33');
# Logic SQL: INSERT INTO t_order(order_id, user_id, content) VALUES(1, 1, 'TEST11'), (2, 2, 'TEST22'), (3, 3, 'TEST33')
# Actual SQL: ds_0 ::: INSERT INTO t_order_0(order_id, user_id, content_cipher, content_plain) VALUES(2, 2, 'mzIhTs2MD3dI4fqCc5nF/Q==', 'TEST22')
# Actual SQL: ds_1 ::: INSERT INTO t_order_1(order_id, user_id, content_cipher, content_plain) VALUES(1, 1, '3qpLpG5z6AWjRX2sRKjW2g==', 'TEST11'), (3, 3, 'oVkQieUbS3l/85axrf5img==', 'TEST33') INSERT INTO t_order_item(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (2, 2, 2, 'TEST22'), (3, 3, 3, 'TEST33');
# Logic SQL: INSERT INTO t_order_item(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (2, 2, 2, 'TEST22'), (3, 3, 3, 'TEST33')
# Actual SQL: ds_0 ::: INSERT INTO t_order_item_0(item_id, order_id, user_id, content) VALUES(2, 2, 2, 'TEST22')
# Actual SQL: ds_1 ::: INSERT INTO t_order_item_1(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (3, 3, 3, 'TEST33') INSERT INTO t_user(user_id, telephone) VALUES(1, '11111111111'), (2, '22222222222'), (3, '33333333333');
# Logic SQL: INSERT INTO t_user(user_id, telephone) VALUES(1, '11111111111'), (2, '22222222222'), (3, '33333333333')
# Actual SQL: ds_0 ::: INSERT INTO t_user(user_id, telephone_cipher, telephone_plain) VALUES(1, 'jFZBCI7G9ggRktThmMlClQ==', '11111111111'), (2, 'lWrg5gaes8eptaQkUM2wtA==', '22222222222'), (3, 'jeCwC7gXus4/1OflXeGW/w==', '33333333333')
SELECT * FROM t_order WHERE user_id = 1 AND order_id = 1;
# Logic SQL: SELECT * FROM t_order WHERE user_id = 1 AND order_id = 1
# Actual SQL: ds_1_slave_0 ::: SELECT order_id, user_id, content_plain, content_cipher FROM t_order_1 WHERE user_id = 1 AND order_id = 1 SELECT * FROM t_order_item WHERE user_id = 1 AND order_id = 1;
# Logic SQL: SELECT * FROM t_order_item WHERE user_id = 1 AND order_id = 1
# Actual SQL: ds_1_slave_1 ::: SELECT * FROM t_order_item_1 WHERE user_id = 1 AND order_id = 1 SELECT * FROM t_user WHERE user_id = 1;
# Logic SQL: SELECT * FROM t_user WHERE user_id = 1
# Actual SQL: ds_0 ::: SELECT user_id, telephone_plain, telephone_cipher FROM t_user WHERE user_id = 1
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ms_ds_${0..1}.t_order_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_inline
t_order_item:
actualDataNodes: ms_ds_${0..1}.t_order_item_${0..1}
tableStrategy:
standard:
shardingColumn: order_id
shardingAlgorithmName: t_order_item_inline
bindingTables:
- t_order,t_order_item
broadcastTables:
- t_config
defaultDatabaseStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none: shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ms_ds_${user_id % 2}
t_order_inline:
type: INLINE
props:
algorithm-expression: t_order_${order_id % 2}
t_order_item_inline:
type: INLINE
props:
algorithm-expression: t_order_item_${order_id % 2} - !READWRITE_SPLITTING
dataSources:
ms_ds_0:
writeDataSourceName: ds_0
readDataSourceNames:
- ds_0_slave_0
- ds_0_slave_1
loadBalancerName: ROUND_ROBIN
ms_ds_1:
writeDataSourceName: ds_1
readDataSourceNames:
- ds_1_slave_0
- ds_1_slave_1
loadBalancerName: ROUND_ROBIN - !ENCRYPT
encryptors:
aes_encryptor:
type: AES
props:
aes-key-value: 123456abc
tables:
t_order:
columns:
content:
plainColumn: content_plain
cipherColumn: content_cipher
encryptor: aes_encryptor
t_user:
columns:
telephone:
plainColumn: telephone_plain
cipherColumn: telephone_cipher
encryptor: aes_encryptor
CREATE TABLE t_order(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100));
# Logic SQL: CREATE TABLE t_order(order_id INT(11) PRIMARY KEY, user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content_cipher VARCHAR(100), content_plain VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content_cipher VARCHAR(100), content_plain VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_0(order_id INT(11) PRIMARY KEY, user_id INT(11), content_cipher VARCHAR(100), content_plain VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_1(order_id INT(11) PRIMARY KEY, user_id INT(11), content_cipher VARCHAR(100), content_plain VARCHAR(100)) CREATE TABLE t_order_item(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100));
# Logic SQL: CREATE TABLE t_order_item(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_item_0(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_order_item_1(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_item_0(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100))
# Actual SQL: ds_0 ::: CREATE TABLE t_order_item_1(item_id INT(11) PRIMARY KEY, order_id INT(11), user_id INT(11), content VARCHAR(100)) CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone VARCHAR(100));
# Logic SQL: CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone VARCHAR(100))
# Actual SQL: ds_1 ::: CREATE TABLE t_user(user_id INT(11) PRIMARY KEY, telephone_cipher VARCHAR(100), telephone_plain VARCHAR(100))
INSERT INTO t_order(order_id, user_id, content) VALUES(1, 1, 'TEST11'), (2, 2, 'TEST22'), (3, 3, 'TEST33');
# Logic SQL: INSERT INTO t_order(order_id, user_id, content) VALUES(1, 1, 'TEST11'), (2, 2, 'TEST22'), (3, 3, 'TEST33')
# Actual SQL: ds_1 ::: INSERT INTO t_order_1(order_id, user_id, content_cipher, content_plain) VALUES(1, 1, '3qpLpG5z6AWjRX2sRKjW2g==', 'TEST11'), (3, 3, 'oVkQieUbS3l/85axrf5img==', 'TEST33')
# Actual SQL: ds_0 ::: INSERT INTO t_order_0(order_id, user_id, content_cipher, content_plain) VALUES(2, 2, 'mzIhTs2MD3dI4fqCc5nF/Q==', 'TEST22') INSERT INTO t_order_item(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (2, 2, 2, 'TEST22'), (3, 3, 3, 'TEST33');
# Logic SQL: INSERT INTO t_order_item(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (2, 2, 2, 'TEST22'), (3, 3, 3, 'TEST33')
# Actual SQL: ds_1 ::: INSERT INTO t_order_item_1(item_id, order_id, user_id, content) VALUES(1, 1, 1, 'TEST11'), (3, 3, 3, 'TEST33')
# Actual SQL: ds_0 ::: INSERT INTO t_order_item_0(item_id, order_id, user_id, content) VALUES(2, 2, 2, 'TEST22') INSERT INTO t_user(user_id, telephone) VALUES(1, '11111111111'), (2, '22222222222'), (3, '33333333333');
# Logic SQL: INSERT INTO t_user(user_id, telephone) VALUES(1, '11111111111'), (2, '22222222222'), (3, '33333333333')
# Actual SQL: ds_1 ::: INSERT INTO t_user(user_id, telephone_cipher, telephone_plain) VALUES(1, 'jFZBCI7G9ggRktThmMlClQ==', '11111111111'), (2, 'lWrg5gaes8eptaQkUM2wtA==', '22222222222'), (3, 'jeCwC7gXus4/1OflXeGW/w==', '33333333333')
SELECT * FROM t_order WHERE user_id = 1 AND order_id = 1;
# Logic SQL: SELECT * FROM t_order WHERE user_id = 1 AND order_id = 1
# Actual SQL: ds_1_slave_0 ::: SELECT `t_order_1`.`order_id`, `t_order_1`.`user_id`, `t_order_1`.`content_cipher` AS `content` FROM t_order_1 WHERE user_id = 1 AND order_id = 1 SELECT * FROM t_order_item WHERE user_id = 1 AND order_id = 1;
# Logic SQL: SELECT * FROM t_order_item WHERE user_id = 1 AND order_id = 1
# Actual SQL: ds_1_slave_1 ::: SELECT * FROM t_order_item_1 WHERE user_id = 1 AND order_id = 1 SELECT * FROM t_user WHERE user_id = 1;
# Logic SQL: SELECT * FROM t_user WHERE user_id = 1
# Actual SQL: ds_1_slave_0 ::: SELECT `t_user`.`user_id`, `t_user`.`telephone_cipher` AS `telephone` FROM t_user WHERE user_id = 1
结语
参考文档
Apache ShardingSphere 5.0.0 内核优化及升级指南的更多相关文章
- 重磅|Apache ShardingSphere 5.0.0 即将正式发布
Apache ShardingSphere 5.0.0 GA 版在经历 5.0.0-alpha 及 5.0.0-beta 接近两年时间的研发和打磨,终于将在 11 月份与大家正式见面! 11 月 10 ...
- Apache Dolphin Scheduler 3.0.1 发布,对核心及UI相关进行优化
点亮 ️ Star · 照亮开源之路 GitHub:https://github.com/apache/dolphinscheduler 版本发布 感谢本次的 Release Manager -- ...
- Apache Spark 2.2.0 中文文档
Apache Spark 2.2.0 中文文档 - 快速入门 | ApacheCN Geekhoo 关注 2017.09.20 13:55* 字数 2062 阅读 13评论 0喜欢 1 快速入门 使用 ...
- Apache Hadoop 3.0.0 Release Notes
http://hadoop.apache.org/docs/r3.0.0/hadoop-project-dist/hadoop-common/release/3.0.0/RELEASENOTES.3. ...
- Apache Kafka分布式流处理平台及大厂面试宝典v3.0.0
概述 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 Apache Kafka官网地址 http://kafka.apache.org/ 最新版本为 3.0.0 Apach ...
- Apache Spark 2.2.0 中文文档 - Spark SQL, DataFrames and Datasets Guide | ApacheCN
Spark SQL, DataFrames and Datasets Guide Overview SQL Datasets and DataFrames 开始入门 起始点: SparkSession ...
- Apache Spark 2.2.0 中文文档 - SparkR (R on Spark) | ApacheCN
SparkR (R on Spark) 概述 SparkDataFrame 启动: SparkSession 从 RStudio 来启动 创建 SparkDataFrames 从本地的 data fr ...
- Apache Kafka 1.0.0正式发布!
千呼万唤始出来,经过7年的发展与完善,Apache Kafka 1.0.0正式发布!在笔者看来,比起1.0.0引入的新功能,此版本最大的意义在于标识Kafka各种组件功能的稳定性.不过我们还是来看下1 ...
- Apache Spark 2.2.0 中文文档 - GraphX Programming Guide | ApacheCN
GraphX Programming Guide 概述 入门 属性 Graph 示例属性 Graph Graph 运算符 运算符的汇总表 Property 运算符 Structural 运算符 Joi ...
随机推荐
- 2021record
2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...
- 微信小程序内判断是否关注公众号(JAVA)
微信小程序内判断是否关注公众号(JAVA) 思路来源(第二种): https://blog.csdn.net/Yanheeee/article/details/117295643 /** * 总体思路 ...
- CountBoard 是一个基于Tkinter简单的,开源的桌面日程倒计时应用
CountBoard 是一个基于Tkinter简单的,开源的桌面日程倒计时应用. 项目地址 https://github.com/Gaoyongxian666/CountBoard 基本功能 置顶功能 ...
- .net Xml加密解密操作
生成密钥的方法: /// <summary>生成RSA加密 解密的 密钥 /// 生成的key就是 方法EncryptByRSA与DecryptByRSA用的key了 /// </s ...
- Spring 5 中函数式web开发中的swagger文档
Spring 5 中一个非常重要的更新就是增加了响应式web开发WebFlux,并且推荐使用函数式风格(RouterFunction和 HandlerFunction)来开发WebFlux.对于之前主 ...
- 六步教你如何用PADS进行PCB设计?
在使用PADS进行PCB设计的过程中,需要对印制板的设计流程以及相关的注意事项进行重点关注,这样才能更好的为工作组中的设计人员提供系统的设计规范,同时也方便设计人员之间进行相互的交流和检查. 02 设 ...
- Spring:面向切面编程的AOP
一.前言 除了依赖注入(DI),Spring框架提供的另一个核心功能是对面向方面的编程(AOP)的支持. AOP通常被称为实现横切关注点的工具.横切关注点一词是指应用程序中的逻辑不能与应用程序的其余部 ...
- 机器人的运动范围 牛客网 剑指Offer
机器人的运动范围 牛客网 剑指Offer 题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大 ...
- cf 24 Game (观察+.. 想一想)
题意: 给一个数N,从1到N. 每次取两个数,三种操作:加.减.乘,运算完得一个数,把那俩数删了,把这个数加进去. 重复操作N-1次. 问是否可能得到24.若可以,输出每一步操作. 思路: 小于4,不 ...
- Java项目中集成钉钉机器人推送消息提醒
前言: 项目中有一个需求,当有新订单产生的时候,希望能够及时通知到业务相关人员进行处理,整体考虑了一下,选用了钉钉机器人提醒功能(公司内部主要也是使用钉钉进行通讯). 操作: 主要分为两部分进行处理: ...