在《ClickHouse原理解析与应用实战》一书244页,也就是副本与分片这一章,作者在介绍分布式表引擎写入的核心流程时,对含有副本的分布式表介绍了2种方式:(1)通过Distributed表引擎自身完成副本的写入 (2)通过ReplicatedMergeTree复制数据
通过ReplicatedMergeTree复制数据的原理是:创建分布式表的本地表时,本地表的表引擎要用ReplicatedMergeTree,然后在集群配置文件的shard标签中加入下面的代码:
<internal_replication>true</internal_replication>
这种写入副本的方式比第一种要好一些,因为第一种Distributed节点既要负责分片也要负责副本的写入工作,压力过大,可能会成为单点瓶颈。
问题1:如果你按照书上的案例,一步一步做下来,会发现第二种方式不生效,也就是你按如下配置以后,副本节点并没有数据同步过去
<!-- 先创建本地表 -->
CREATE TABLE test_sharding_simple2_local ON CLUSTER sharding_simple_1(
id UInt64
)ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_sharding_simple2','{replica}')
ORDER BY id
<!-- 再创建分布式表 -->
CREATE TABLE test_sharding_simple2_all(
id UInt64
)ENGINE = Distributed(sharding_simple_1',default,test_sharding_simple2_local,rand())
<!-- 往分布式表写入数据 -->
INSERT INTO test_sharding_simple2_all values(1),(23),(800)
执行以上sql以后,分片节点查询分布式表和本地表都有数据,但是副本节点没有数据。原因是这样的:如果你跟着书上的案例顺序练,在这个案例之前,作者先演示了一个2个分片的集群,并且在每个节点的config.xml中配置了宏变量:
<!-- 节点1的宏变量 -->
<macros>
<shard>01</shard>
<replica>ch5.nauu.com</replica>
</macros>
<!-- 节点2的宏变量 -->
<macros>
<shard>02</shard>
<replica>ch6.nauu.com</replica>
</macros>
2个分片的集群这么定义没问题,后来作者演示1分片1副本的集群时,没在书中注明需要改这些宏变量的配置,因为现在是1分片1副本,那么节点2的宏变量也必须是节点1的分片号,即2个节点的分片号必须一样,因为只有一个分片啊,你要是2个节点分片号还不一样,那永远也不会有副本同步,正确的配置如下:
<!-- 节点1的宏变量 -->
<macros>
<shard>01</shard>
<replica>ch5.nauu.com</replica>
</macros>
<!-- 节点2的宏变量. 注意:一分片一副本的情况下,两个节点的shard标签里的值必须一样 -->
<macros>
<shard>01</shard>
<replica>ch6.nauu.com</replica>
</macros>
这么配置以后,重启集群,然后就可以了。
问题2:在第260页,作者介绍数据行级权限时,在user.xml配置文件中为自定义用户标签<user_normal/>中的test_row_level表使用了filter标签增加过滤条件id<10,当你按照书中这样做了以后,因为要使配置生效必须重启集群 ,但是重启报错了,报invalid token,这是因为在xml中配置大于小于号,要转义,正确的配置如下:
<!-- 为test_row_level表增加过滤条件 id < 10 -->
<test_row_level>
<filter>id <![CDATA[<]] 10</filter>
</test_row_level>
问题3:在第268页,作者介绍part_log日志时,这个日志默认是关闭的,需要去config.xml中打开注释,重启集群。重启完以后,你按照书上的sql去查询system.part_log表,但是却报错了,提示system.part_log doesn't exist,说这个表不存在。这是因为你刚把这项配置打开,只有新操作分区表时,才会生成记录,而且这个表是惰性加载,只有操作过分区,才会生成这个表。此时你执行一下select查询之前创建过的MergeTree表,然后按照书上的sql去查询system.part_log表,已经有数据了