【免费下载链接】pulsar
Apache Pulsar - distributed pub-sub messaging system
本指南以 Apache Pulsar 的 IO 框架为主线,通过完整实操演示如何在不编写一行业务代码的前提下,将 Pulsar 集群中的消息实时写入 Apache Cassandra 数据库。你将掌握 Pulsar 二进制发行包与内置连接器(Builtin Connectors)的安装、Standalone 模式的启动与健康检查,以及使用 pulsar-admin CLI 创建、查看、验证和删除 Cassandra Sink 连接器的完整流程,并理解 Sink 连接器在 Pulsar Functions 运行时上的底层工作原理。
Pulsar IO 与 Sink 连接器概述
Pulsar IO 连接器(Connector)是 Pulsar 与外部系统集成的核心机制,分为两种类型:
- Source(源):将数据从外部系统送入 Pulsar,例如 Kafka、RabbitMQ、Twitter Firehose 等;
- Sink(汇):将数据从 Pulsar 导出到外部系统,例如 Cassandra、Aerospike、Kinesis、Elasticsearch 等 SQL/NoSQL 数据库。
本教程的主角是 Cassandra Sink 连接器:它订阅 Pulsar 中的一个 topic,把每一条消息作为一行写入 Cassandra 的指定 keyspace 和表中,全程无需编写任何代码。Pulsar IO 连接器在架构上是 Pulsar Functions 的一种运行形态——从源码看,Cassandra Sink 实现类 CassandraStringSink 直接实现了 Pulsar Functions API 中的 Sink<byte[]> 接口(见 CassandraStringSink.java),因此你之后可以复用 Functions CLI 来监控和管理它。
背景提示:自
2.1.0-incubating起,Pulsar 将内置连接器拆分为独立的二进制发行包发布。本指南的所有命令在单机 Standalone 模式下可直接运行,在多节点集群中同样适用,无需任何改动。
安装 Pulsar 二进制发行包
本教程的全部命令都基于 Pulsar 二进制发行包的根目录 执行。获取发行包有几种方式:
- 从 Apache 镜像站下载
apache-pulsar-<version>-bin.tar.gz; - 访问 Pulsar 官方 Downloads 页面或 Releases 页面获取最新版本链接;
- 使用
wget下载(将<binary_release_url>替换为实际下载地址):
$ wget pulsar:binary_release_url
下载完成后解压并进入目录:
$ tar xvfz apache-pulsar-<version>-bin.tar.gz
$ cd apache-pulsar-<version>
安装内置连接器(Builtin Connectors)
从 2.1.0-incubating 版本开始,Pulsar 将全部内置连接器放在一个独立的二进制发行包中,需要用以下任一方式单独获取:
- 从 Apache 镜像下载
apache-pulsar-io-connectors-<version>-bin.tar.gz; - 从 Pulsar Downloads 页面或 Releases 页面获取;
- 使用
wget:
$ wget pulsar:connector_release_url
解压并复制 connectors 目录到 Pulsar 根目录下:
$ tar xvfz /path/to/apache-pulsar-io-connectors-<version>-bin.tar.gz
// 解压后在 pulsar 目录下会得到名为 apache-pulsar-io-connectors-<version> 的目录
// 将其中的 connectors 复制出来
$ cp -r apache-pulsar-io-connectors-<version>/connectors connectors
$ ls connectors
pulsar-io-aerospike-<version>.nar
pulsar-io-cassandra-<version>.nar
pulsar-io-kafka-<version>.nar
pulsar-io-kinesis-<version>.nar
pulsar-io-rabbitmq-<version>.nar
pulsar-io-twitter-<version>.nar
...
每个连接器都是一个 NAR 归档(.nar 后缀),其中打包了连接器实现及其全部依赖。以 Cassandra 连接器为例,其 Maven 模块 pulsar-io/cassandra/pom.xml 使用 nifi-nar-maven-plugin 构建,并依赖 pulsar-io-core(IO 核心 API)与 cassandra-driver-core(DataStax Cassandra 驱动)。Pulsar 的 Functions Worker 在启动时通过 ConnectorUtils.searchForConnectors 扫描 connectors 目录下的所有 *.nar 文件,读取每个 NAR 内的 pulsar-io.yaml 服务描述文件,即可自动发现并注册全部内置连接器。
注意:
pulsar-admin sink create命令中的--sink-type参数值(例如cassandra)由连接器 NAR 内pulsar-io.yaml中设置的name字段决定,而非随意指定。
启动 Pulsar 服务并完成健康检查
在 Pulsar 根目录下启动单机版 Pulsar:
bin/pulsar standalone
Standalone 模式会按顺序启动 Pulsar 的全部组件(BookKeeper、Broker、ZooKeeper、Functions Worker 等)。启动完成后,通过以下四个检查点确认服务就绪:
1. 检查 Pulsar 二进制协议端口(6650):
telnet localhost 6650
2. 检查 Pulsar Functions 集群状态:
curl -s http://localhost:8080/admin/v2/functions/cluster
示例输出:
[{"workerId":"c-standalone-fw-localhost-6750","workerHostname":"localhost","port":6750}]
3. 确认 public tenant 与 default namespace 存在:
curl -s http://localhost:8080/admin/v2/namespaces/public
示例输出:
["public/default","public/functions"]
4. 确认所有内置连接器均已被发现:
curl -s http://localhost:8080/admin/v2/functions/connectors
示例输出:
[{"name":"aerospike","description":"Aerospike database sink","sinkClass":"org.apache.pulsar.io.aerospike.AerospikeStringSink"},{"name":"cassandra","description":"Writes data into Cassandra","sinkClass":"org.apache.pulsar.io.cassandra.CassandraStringSink"},{"name":"kafka","description":"Kafka source and sink connector","sourceClass":"org.apache.pulsar.io.kafka.KafkaStringSource","sinkClass":"org.apache.pulsar.io.kafka.KafkaStringSink"},{"name":"kinesis","description":"Kinesis sink connector","sinkClass":"org.apache.pulsar.io.kinesis.KinesisSink"},{"name":"rabbitmq","description":"RabbitMQ source connector","sourceClass":"org.apache.pulsar.io.rabbitmq.RabbitMQSource"},{"name":"twitter","description":"Ingest data from Twitter firehose","sourceClass":"org.apache.pulsar.io.twitter.TwitterFireHose"}]
响应中的 sinkClass 字段明确列出了 cassandra 对应的实现类 org.apache.pulsar.io.cassandra.CassandraStringSink,该类的 @Connector(name = "cassandra", type = IOType.SINK) 注解(见 CassandraStringSink.java)正是连接器被自动发现与注册的依据。
若启动过程报错,可以在运行 pulsar standalone 的终端看到异常堆栈,也可以查看 Pulsar 目录下 logs 目录中的日志文件定位问题。
在 Docker 中搭建单节点 Cassandra
接下来的步骤需要本机安装 Docker。使用官方 cassandra 镜像启动一个单节点 Cassandra 集群:
docker run -d --rm --name=cassandra -p 9042:9042 cassandra
-p 9042:9042将容器内的 CQL 原生协议端口映射到宿主机,便于 Pulsar Sink 从宿主机网络访问。
继续之前,用三种方式确认 Cassandra 已就绪:
1. 确认 Docker 进程在运行:
docker ps
2. 检查 Cassandra 日志,确认进程正常启动:
docker logs cassandra
3. 使用 nodetool 检查集群状态:
docker exec cassandra nodetool status
示例输出:
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.17.0.2 103.67 KiB 256 100.0% af0e4b2f-84e0-4f0b-bb14-bd5f9070ff26 rack1
UN(Up/Normal)表示节点状态正常,可继续后续步骤。
创建 keyspace 与表
使用 cqlsh 连接 Cassandra:
$ docker exec -ti cassandra cqlsh localhost
Connected to Test Cluster at localhost:9042.
[cqlsh 5.0.1 | Cassandra 3.11.2 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh>
以下命令均在 cqlsh 提示符中执行。
创建 keyspace:
cqlsh> CREATE KEYSPACE pulsar_test_keyspace WITH replication = {'class':'SimpleStrategy', 'replication_factor':1};
创建表:
cqlsh> USE pulsar_test_keyspace;
cqlsh:pulsar_test_keyspace> CREATE TABLE pulsar_test_table (key text PRIMARY KEY, col text);
编写 Cassandra Sink 配置文件
Cassandra Sink 连接器会从 Pulsar topic 读取消息并写入 Cassandra 表。运行时它需要一个 YAML 配置文件,告知 Pulsar IO 如何定位 Cassandra 集群、使用哪个 keyspace 和表来落库。
新建文件 examples/cassandra-sink.yml,填入以下内容:
configs:
roots: "localhost:9042"
keyspace: "pulsar_test_keyspace"
columnFamily: "pulsar_test_table"
keyname: "key"
columnName: "col"
配置项说明(与源码一一对应)
下表字段与 CassandraSinkConfig.java 中定义的属性完全一致,全部为必填项:
| 配置项 | 类型 | 必填 | 说明 |
|---|---|---|---|
roots | String | 是 | 逗号分隔的 Cassandra 主机列表,格式为 host:port,用于建立连接。 |
keyspace | String | 是 | 用于写入 Pulsar 消息的 keyspace,必须在启动 Sink 前预先创建。 |
keyname | String | 是 | Cassandra 列族中用于存储 Pulsar 消息 key 的列名;若消息没有关联 key,则使用消息 value 作为 key。 |
columnFamily | String | 是 | Cassandra 列族(表)名称,必须在启动 Sink 前预先创建。 |
columnName | String | 是 | 列族中用于存储 Pulsar 消息 value 的列名。 |
从实现层面看,Sink 启动时调用 CassandraSinkConfig.load(config) 解析配置,并校验上述五个字段是否为空,任一缺失都会抛出 IllegalArgumentException("Required property not set.")(见 CassandraAbstractSink.java)。roots 支持以逗号分隔的多个主机,内部通过 host:port 解析后逐个添加为 contact point。
提交 Cassandra Sink 连接器
Pulsar 提供了 pulsar-admin CLI 用于运行和管理 IO 连接器(完整的命令参考见 reference-pulsar-admin.md)。执行以下命令,以 cassandra 类型和刚才编写的配置文件提交一个名为 cassandra-test-sink 的 Sink:
bin/pulsar-admin sink create \
--tenant public \
--namespace default \
--name cassandra-test-sink \
--sink-type cassandra \
--sinkConfigFile examples/cassandra-sink.yml \
--inputs test_cassandra
命令执行成功后,Pulsar 会创建一个名为 cassandra-test-sink 的 Sink 连接器。它以 Pulsar Function 的形态运行:订阅输入 topic test_cassandra,将消息写入 Cassandra 表 pulsar_test_table。
查看与检查 Sink 运行状态
由于 IO 连接器本质上运行在 Pulsar Functions 运行时上,因此可以复用 Functions CLI 进行查看和管理。
获取 Sink 配置信息
bin/pulsar-admin functions get \
--tenant public \
--namespace default \
--name cassandra-test-sink
示例输出:
{
"tenant": "public",
"namespace": "default",
"name": "cassandra-test-sink",
"className": "org.apache.pulsar.functions.api.utils.IdentityFunction",
"autoAck": true,
"parallelism": 1,
"source": {
"topicsToSerDeClassName": {
"test_cassandra": ""
}
},
"sink": {
"configs": "{\"roots\":\"cassandra\",\"keyspace\":\"pulsar_test_keyspace\",\"columnFamily\":\"pulsar_test_table\",\"keyname\":\"key\",\"columnName\":\"col\"}",
"builtin": "cassandra"
},
"resources": {}
}
可以看到,sink.builtin 字段标记为 cassandra,sink.configs 中携带了我们在 YAML 中声明的全部连接参数,source.topicsToSerDeClassName 则列出了输入 topic test_cassandra。
检查 Sink 运行状态
bin/pulsar-admin functions getstatus \
--tenant public \
--namespace default \
--name cassandra-test-sink
示例输出:
{
"functionStatusList": [
{
"running": true,
"instanceId": "0",
"metrics": {
"metrics": {
"__total_processed__": {},
"__total_successfully_processed__": {},
"__total_system_exceptions__": {},
"__total_user_exceptions__": {},
"__total_serialization_exceptions__": {},
"__avg_latency_ms__": {}
}
},
"workerId": "c-standalone-fw-localhost-6750"
}
]
}
running: true 表示 Sink 实例(instanceId: 0)已正常运行在 Functions Worker(c-standalone-fw-localhost-6750)上。
生产消息并验证数据落库
向 Sink 的输入 topic test_cassandra 生产 10 条消息:
for i in {0..9}; do bin/pulsar-client produce -m "key-$i" -n 1 test_cassandra; done
再次查看 Sink 状态,应能看到 10 条消息已被成功处理:
bin/pulsar-admin functions getstatus \
--tenant public \
--namespace default \
--name cassandra-test-sink
示例输出:
{
"functionStatusList": [
{
"running": true,
"numProcessed": "11",
"numSuccessfullyProcessed": "11",
"lastInvocationTime": "1532031040117",
"instanceId": "0",
"metrics": {
"metrics": {
"__total_processed__": {
"count": 5.0,
"sum": 5.0,
"max": 5.0
},
"__total_successfully_processed__": {
"count": 5.0,
"sum": 5.0,
"max": 5.0
},
"__total_system_exceptions__": {},
"__total_user_exceptions__": {},
"__total_serialization_exceptions__": {},
"__avg_latency_ms__": {}
}
},
"workerId": "c-standalone-fw-localhost-6750"
}
]
}
numProcessed 与 numSuccessfullyProcessed 均为 11,说明 10 条消息加上启动初始化均已成功处理,无系统异常与用户异常。
最后进入 cqlsh 验证 Cassandra 中的数据:
docker exec -ti cassandra cqlsh localhost
查询 pulsar_test_table 表中的数据:
cqlsh> use pulsar_test_keyspace;
cqlsh:pulsar_test_keyspace> select * from pulsar_test_table;
key | col
--------+--------
key-5 | key-5
key-0 | key-0
key-9 | key-9
key-2 | key-2
key-1 | key-1
key-3 | key-3
key-6 | key-6
key-7 | key-7
key-4 | key-4
key-8 | key-8
10 条消息(key-0 到 key-9)全部写入成功。这是因为 CassandraStringSink 将输入消息视为字符串,并生成 key 与 value 完全相同的键值对:若消息自带 key 则使用消息 key,否则用消息 value 充当 key。写入路径上,CassandraAbstractSink.write 通过预编译的 INSERT INTO <columnFamily> (<keyname>, <columnName>) VALUES (?, ?) 语句异步执行插入,成功回调 record.ack() 确认消息,失败则回调 record.fail() 触发重试——这也是 Pulsar IO Sink 侧 at-least-once 语义的实现基础。
删除 Cassandra Sink
验证完毕后,可以清理掉该 Sink 连接器:
bin/pulsar-admin sink delete \
--tenant public \
--namespace default \
--name cassandra-test-sink
延伸阅读
- 阅读 Pulsar IO 概念与 Source/Sink 架构,了解处理语义(
at-most-once、at-least-once、effectively-once)与连接器管理方式; - 查看 内置连接器清单 与 连接器管理指南,掌握 source/sink 的创建、更新、监控与升级方法;
- 当前 Cassandra Sink 连接器的完整配置属性说明见 io-cassandra-sink.md,其 JSON 格式配置与 YAML 等价;
- 若需了解连接器如何被打包为 NAR 并通过
pulsar-io.yaml声明元数据,可阅读 io-develop.md 并对照源码 ConnectorUtils.java; - 单机模式的其他用法可参考 getting-started-standalone.md 与 standalone.md。
【免费下载链接】pulsar
Apache Pulsar - distributed pub-sub messaging system
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



