Bootstrap

apache-pulsar-2.10.0集群复制详解

apache-pulsar-2.10.0集群复制详解


​ 本文将展示如何基于apache-pulsar-2.10.0实现Geo-Replication

1 Geo-Replication简介

​ Geo-Replication,字面理解就是跨网段的数据中心间的实时数据备份,所以主要应用一般也是指物理上跨区域的数据中心间的实时数据备份,实现容灾备份和灾难恢复;基于Geo-Replication,还可以衍生出很多应用场景;

​ 相关内容更系统的可以去看pulsar官网的内容(下面两个链接,第一个是介绍些概念,第二个说基本操作):

​ https://pulsar.apache.org/docs/next/concepts-replication

​ https://pulsar.apache.org/docs/next/administration-geo

1.1 复制机制

​ 分两种:

  1. 同步复制(Synchronous geo-replication),低延迟,弱一致性;
  2. 异步复制,Asynchronous geo-replication,高可用性,强一致性,高延迟;

1.2 复制方式

1.2.1 全网复制(Full-mesh replication)

​ 数据在所有数据中心间中共享;

1.2.1.1 两两复制(Active-active replication)

​ 只有两个数据中心的全网复制,同时对外提供服务;

1.2.1.2 双心热备(Active-standby replication)

​ 只有两个数据中心的全网复制,但数据只写到活数据中心,从活数据中心复制到备份数据中心;

1.2.2 聚集复制(Aggregation replication)

​ 多数据中心数据向一个数据中心汇集;

2 环境准备

​ 这里介绍两个数据中心间的同步数据复制;

2.1 操作系统和基本软件版本

项目版本
OSCentOS 7
JDKJDK 8
pulsarpulsar-2.10.0

2.2 Pulsar集群组成

  • ZooKeeper 集群(3(或多) 个 ZooKeeper 节点组成)
  • Bookie 集群(也称为 BookKeeper 集群,3(或多) 个 BookKeeper 节点组成)
  • Broker 集群(3(或多) 个 Pulsar 节点组成)
  • ConfigurationStore集群(3(或多) 个 ZooKeeper 节点组成)

3 ConfigurationStore安装

3.1 安装机器

​ 指定三台机器,ip示例如下:

  • 192.168.123.101

  • 192.168.123.102

  • 192.168.123.103

    注意,/etc/hostname,/etc/hosts一定要严格配置好,例如:

    #/etc/hostname
    centos7-pulsar-c11
    
    #/etc/hosts
    192.168.123.101	centos7-pulsar-c11
    192.168.123.102	centos7-pulsar-c12
    192.168.123.103	centos7-pulsar-c13
    192.168.123.111	centos7-pulsar-c21
    192.168.123.112	centos7-pulsar-c22
    192.168.123.113	centos7-pulsar-c23
    

3.2 配置

#在192.168.123.101, 192.168.123.102, 192.168.123.103上分别创建目录
mkdir -pv /home/bigdata/data/zookeeper/global
mkdir -pv /home/bigdata/dataLog/zookeeper/global

#192.168.123.101上执行
echo 1 > /home/bigdata/data/zookeeper/global/myid 
#192.168.123.102上执行
echo 2 > /home/bigdata/data/zookeeper/global/myid 
#192.168.123.103上执行
echo 3 > /home/bigdata/data/zookeeper/global/myid

#分别修改三台global_zookeeperr配置
mv /home/bigdata/apps/pulsar/conf/global_zookeeper.conf /home/bigdata/apps/pulsar/conf/global_zookeeper.conf_bk
vi /home/bigdata/apps/pulsar/conf/global_zookeeper.conf

三台机器上zookeeper配置如下:

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/bigdata/data/zookeeper/global
dataLogDir=/home/bigdata/dataLog/zookeeper/global
clientPort=2185
admin.enableServer=true
admin.serverPort=19990
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
forceSync=yes
sslQuorum=false
portUnification=false
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
metricsProvider.httpPort=8710
metricsProvider.exportJvmInfo=true
server.1=192.168.123.101:12888:13888
server.2=192.168.123.102:12888:13888
server.3=192.168.123.103:12888:13888

3.3 启动

#分别启动三台configuration-store: 执行后台运行命令
./bin/pulsar-daemon start configuration-store

#停止configuration-store命令
./bin/pulsar-daemon stop configuration-store

#查看端口启动情况
netstat -tpnl |grep 2185

#查看进程占用端口情况
netstat -tpnl |grep pid

3 集群1安装

3.1 配置修改

​ 为了避免做过多重复的事情 ,这里从原始安装包解压后的目录开始配置,在一台机器上配置完成后再复制到其它机器上,所以Zookeeper、BookKeeper、Broker三种组件的配置先按以下步骤进行,完成后再复制到其它机器上,在其它机器上单独对BookKeeper、Broker的配置进行局部修改即可;

3.1.1 Zookeeper配置文件修改

#在192.168.123.101, 192.168.123.102, 192.168.123.103上分别创建目录
mkdir -pv /home/bigdata/data/zookeeper/cluster
mkdir -pv /home/bigdata/dataLog/zookeeper/cluster

#192.168.123.101上执行
echo 11 > /home/bigdata/data/zookeeper/cluster/myid 
#192.168.123.102上执行
echo 21 > /home/bigdata/data/zookeeper/cluster/myid 
#192.168.123.103上执行
echo 31 > /home/bigdata/data/zookeeper/cluster/myid

#分别修改三台zookeeper配置
mv /home/bigdata/apps/pulsar/conf/zookeeper.conf /home/bigdata/apps/pulsar/conf/zookeeper.conf_bk
vi /home/bigdata/apps/pulsar/conf/zookeeper.conf

三台机器上zookeeper配置如下:

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/bigdata/data/zookeeper/cluster
dataLogDir=/home/bigdata/dataLog/zookeeper/cluster
clientPort=2188
admin.enableServer=true
admin.serverPort=29990
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
forceSync=yes
sslQuorum=false
portUnification=false
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
metricsProvider.httpPort=18600
metricsProvider.exportJvmInfo=true
server.11=192.168.123.101:17666:13666
server.21=192.168.123.102:17666:13666
server.31=192.168.123.103:17666:13666

3.1.2 BookKeeper配置文件修改

#分别每个节点执行

#创建bookie所需要目录
mkdir -pv /home/bigdata/data/bookkeeper/journal
mkdir -pv /home/bigdata/data/bookkeeper/ledger

#注意下面的配置,修改每个节点对应的ip
# 进入bookie 配置文件目录,编辑 bookkeeper.conf 文件
vim bookkeeper.conf

三台机器上bookkeeper配置如下:

# 修改以下两个文件目录地址
journalDirectory=/home/bigdata/data/bookkeeper/journal
ledgerDirectories=/home/bigdata/data/bookkeeper/ledger

# 修改zk地址和端口信息
zkServers=192.168.123.101:2188,192.168.123.102:2188,192.168.123.103:2188

#httpServerPort默认也是8000,建议修改,我这里修改为:8100
prometheusStatsHttpPort=8100

3.1.3 Broker配置文件修改

分别每个节点执行

vim conf/broker.conf

三台机器上broker配置如下:

# pulsar cluster名,和ZooKeeper里初始化元数据时指定的集群名(--cluster pulsar1)相同
clusterName=pulsar1

# 元数据存储URL
metadataStoreUrl=192.168.123.101:2188,192.168.123.102:2188,192.168.123.103:2188

# 配置数据的元数据存储URL,可以为空,为空将使用metadataStoreUrl
configurationMetadataStoreUrl=192.168.123.101:2185,192.168.123.102:2185,192.168.123.103:2185

# http请求服务端口
webServicePort=18080

分别每个节点执行

vim conf/client.conf

三台机器上client配置如下:

webServiceUrl=http://localhost:18080/

3.2 启动

3.2.2 Zookeeper集群启动

#分别启动三台zookeeper: 执行后台运行命令
./bin/pulsar-daemon start zookeeper

#停止zookeeper命令
./bin/pulsar-daemon stop zookeeper

#查看端口启动情况
netstat -tpnl |grep 2188

#查看进程占用端口情况
netstat -tpnl |grep pid

3.2.3 验证ZooKeeper节点是否启动成功

#执行 zookeeper 客户端连接命令
./bin/pulsar zookeeper-shell -server 127.0.0.1:2188
或
./bin/pulsar zookeeper-shell -server 192.168.123.101:2188
./bin/pulsar zookeeper-shell -server 192.168.123.102:2188
./bin/pulsar zookeeper-shell -server 192.168.123.103:2188

#查看所有zk节点数据,命令如下
ls /

#显示如下,表示zk的集群已经搭建好了
[zookeeper]

3.2.4 初始化Zookeeper集群元数据

#先查看端口占用情况,避免后面启动时会报端口占用错误
netstat -tpnl |grep 8080  
netstat -tpnl |grep 8443
netstat -tpnl |grep 6650
netstat -tpnl |grep 6651

# 在任一个 zooKeeper 节点,如:192.168.123.101,初始化集群元数据
# 进入Apache-pulsar 目录
# 执行命令初始化集群元数据
./bin/pulsar initialize-cluster-metadata \
--cluster pulsar1 \
--zookeeper 192.168.123.101:2188,192.168.123.102:2188,192.168.123.103:2188 \
--configuration-store 192.168.123.101:2185,192.168.123.102:2185,192.168.123.103:2185 \
--web-service-url http://192.168.123.101:18080,192.168.123.102:18080,192.168.123.103:18080 \
--web-service-url-tls https://192.168.123.101:8443,192.168.123.102:8443,192.168.123.103:8443 \
--broker-service-url pulsar://192.168.123.101:6650,192.168.123.102:6650,192.168.123.103:6650 \
--broker-service-url-tls pulsar+ssl://192.168.123.101:6651,192.168.123.102:6651,192.168.123.103:6651

#连接任意一台zookeeper,比如:192.168.123.101
./bin/pulsar zookeeper-shell -server 127.0.0.1:2188
#查询数据
ls /
#显示如下,有bookies,pulsar等信息,表示成功初始化
[admin, bookies, ledgers, pulsar, stream, zookeeper]

3.2.5 BookKeeper集群启动

各个节点配置好后,分别执行以下命令启动BookKeeper:

#启动bookie命令,以后台进程启动bookie
./bin/pulsar-daemon start bookie

bookie关闭命令如下:

./bin/pulsar-daemon stop bookie

验证是否启动成功:

./bin/bookkeeper shell bookiesanity

看到“Bookie sanity test succeeded”表明成功!

3.2.6 Broker集群启动

各个节点配置好后,分别执行以下命令启动Broker:

# 以后台进程启动 broker
./bin/pulsar-daemon start broker

broker关闭命令如下:

./bin/pulsar-daemon stop broker

验证Broker集群是否启动成功

执行以下命令,查看pulsar1集群 brokers 节点情况

./bin/pulsar-admin brokers list pulsar1
或
./bin/pulsar-admin --admin-url http://192.168.123.101:18080 brokers list pulsar1

显示如下:表式集群搭建成功:

$ ./bin/pulsar-admin --admin-url http://192.168.123.101:18080 brokers list pulsar1
192.168.123.102:18080
192.168.123.103:18080
192.168.123.101:18080

4 集群2安装

​ 同“3 集群1安装”一样,注意把以下其中的ip地址,换成集群2中各节点机器的ip地址,集群名称换成新的集群名称,就可以了(zookeeper集群初始化时,configuration-store的配置注意不要弄错),比如:

192.168.123.101 ===》 192.168.123.111
192.168.123.102 ===》 192.168.123.112
192.168.123.103 ===》 192.168.123.113
pulsar1 ===》 pulsar2

​ 然后把相关操作在对应的机器上再操作一次就可以了。

​ 这里给出初始化Zookeeper集群元数据的内容,这一块主要注意configuration-store的配置:

./bin/pulsar initialize-cluster-metadata \
--cluster pulsar2 \
--zookeeper 192.168.123.111:2188,192.168.123.112:2188,192.168.123.113:2188 \
--configuration-store 192.168.123.101:2185,192.168.123.102:2185,192.168.123.103:2185 \
--web-service-url http://192.168.123.111:18080,192.168.123.112:18080,192.168.123.113:18080 \
--web-service-url-tls https://192.168.123.111:8443,192.168.123.112:8443,192.168.123.113:8443 \
--broker-service-url pulsar://192.168.123.111:6650,192.168.123.112:6650,192.168.123.113:6650 \
--broker-service-url-tls pulsar+ssl://192.168.123.111:6651,192.168.123.112:6651,192.168.123.113:6651

5 Geo-Relicationr操作

​ 上面已经配置好了Global Zookeeper Clusters,可以通过它来实现在各个不同数据中心的pulsar集群的同步数据复制,下面的实操主要针对namespace进行,这样一来,网络环境稳定时,指定的namcspace下所有toipc的数据在指定的pulsar集群之间就是完全一致的。

5.1 默认情况下数据共享

​ 在前面所创建的两个集群,pulsar1、pulsar2,目前configuration-store是同一个zookeeper集群,所以租户、名称空间、主题具有唯一性,

​ 换个角度来说,在一个集群里创建的租户名称空间,在另一个集群里能看到同样的名字;

​ 但是对于主题来讲,默认情况下它只属于创建相关名称空间的集群;

5.1.1 租户共享验证

​ 在pulsar1集群创建租户yx-ta:

./bin/pulsar-admin tenants create yx-ta
./bin/pulsar-admin tenants list

image-tenants-list-c11

​ 再到pulsar2集群上查看所有的租户:
image-tenants-list-c21
​ 很显然,pulsar2集群上可以看到pulsar1集群所创建的租户;

5.1.2 名称空间共享验证

​ 在pulsar2集群中操作,在租户yx-ta下创建名称空间yx-ns:

./bin/pulsar-admin namespaces create yx-ta/yx-ns
./bin/pulsar-admin namespaces list yx-ta

image-namespaces-list-c21
​ 再到pulsar1集群上查看yx-ta租户下所有的名称空间:
image-namespaces-list-c11
​ 很显然,pulsar1集群上可以看到pulsar2集群所创建的名称空间;

5.1.3 “主题共享”验证

​ 在pulsar1集群中操作,在租户yx-ta下的yx-ns名称空间下创建一个没有分区的主题yx-tp:

./bin/pulsar-admin topics create persistent://yx-ta/yx-ns/yx-tp
./bin/pulsar-admin topics list yx-ta/yx-ns

image-topics-create-err
​ 很明显,我们看到报错了,我们集群pulsar2中做同样的操作试试:
image-topics-create-succ
可见,在集群pulsar2上创建主题成功了,可以推断,在某集群下,并且在该集群自己的名称空间下创建主题是被允许的;

​ 注意: 不管是有分区还是没有分区, 创建topic后,如果没有任何操作, 60s后pulsar会认为此topic是不活动的, 会自动进行删除, 以避免生成垃圾数据;

​ 再到pulsar1集群上,查看租户yx-ta下的yx-ns名称空间下的所有主题:
image-topics-list-c11-err
​ 很显然,pulsar1集群上看不到租户yx-ta下的yx-ns名称空间下的主题,这样的话,我们能想到的表面原因就是yx-ns这个名称空间不是集群pulsar1下创建的,这样导致在集群pulsar1下无法对不属于该集群的名称空间进行任何操作(创建、删除、修改、查看);

​ 试验一下,在pulsar1集群下能不能创建与pulsar2集群同名租户yx-ta下同名的名称空间yx-ns:
image-namespaces-create-samename-c11-succ
​ 可以看到同时出现了两个yx-ns,其实它们分别属于两个不同的集群;

​ 这样再在集群pulsar1下的yx-ns名称空间下创建主题yx-tp:
image-topics-create-c11-err-2
​ 很显然,还是错误,然后在集群pulsar2下创建主题:

./bin/pulsar-admin topics create persistent://yx-ta/yx-ns/yx-tp2
./bin/pulsar-admin topics list yx-ta/yx-ns

image-topics-create-succ2

​ 可以推断,yx-ns目前只认pulsar2这个集群了;

​ yx-tp这个主题看不到了,是因为操作60s没有与它相关的操作了;

​ 事实上,pulsar设计者在设计namespaces的create指令时,有一个指定集群的参数"-c",当不指定这个参数时,会默认把名称空间分配给执行create namespaces命令的集群上,比如:

#5.1.2中,在集群pulsar2上执行的命令:
./bin/pulsar-admin namespaces create yx-ta/yx-ns

#等价于以下命令:
./bin/pulsar-admin namespaces create -c pulsar2 yx-ta/yx-ns
#上面这个命令不论在哪个集群上执行,都是创建名称空间yx-ns,并把yx-ns分配给pulsar2这个集群

​ 结论:默认情况下,主题在不同集群间不可共享;

5.2 集群间数据复制

​ 就发布订阅是模式MQ集群来说,在集群内部要保证高可靠、高可用,肯定是通过副本机制来保证的;

​ 而集群间数据复制,一般是指跨物理网段的集群间的数据同步;

​ 前面所搭建的两个pulsar集群,已经有了一个数据共享复制的基础,就是依赖一个global zookeeper集群;

5.2.1 名称空间共享实质化

​ 前面在集群pulsar2创建的名称空间yx-ns,在集群pulsar1中能看到,但不能针对yx-ns下的主题进行任何实质性的操作;

​ 把集群pulsar2下的名称空间yx-ns分配给pulsar1,这是一个名称空间共享实质化操作,开启了集群间的数据实时同步功能:

./bin/pulsar-admin namespaces set-clusters --clusters pulsar1,pulsar2 yx-ta/yx-ns
./bin/pulsar-admin namespaces get-clusters yx-ta/yx-ns
./bin/pulsar-admin topics create persistent://yx-ta/yx-ns/yx-tp
./bin/pulsar-admin topics list yx-ta/yx-ns

image-namespaces-set-clusters

​ 可以看出,在集群pulsar1上可以操作yx-ns这个名称空间了;

​ 事实上,此时不论从哪个集群对yx-ns这个名称空间下的内容进行操作,相关操作都会实时同步到另一个集群中去。来试验一下,同时在两个集群里订阅同一个topic,在两个集群中发消息到这个topic,看两边的消费情况:

#订阅,在集群pulsar1、pulsar2
./bin/pulsar-client consume  persistent://yx-ta/yx-ns/yx-tp \
-n 10  -s "a1"   -t "Exclusive"  

#生产,在集群pulsar1
./bin/pulsar-client produce persistent://yx-ta/yx-ns/yx-tp \
  -n 3  -m "Pulsar1 Geo"

#生产,在集群pulsar2
./bin/pulsar-client produce persistent://yx-ta/yx-ns/yx-tp \
  -n 7  -m "Pulsar2 Geo"

​ 集群pulsar1上的生产情况:
image-topics-produce-pulsar1
​ 集群pulsar2上的生产情况:
image-topics-produce-pulsar2
​ 集群pulsar1上的消费情况:
image-topics-consume-pulsar1
​ 集群pulsar2上的消费情况:
image-topics-consume-pulsar2

6 总结

​ 从pulsar集群复制的理论到功能演示,展示了pulsar集群的跨数据中心的数据复制功能;

;