kafka 1.0 中文文档(九):操作

以下是一些基于LinkedIn使用和经验实际在生产系统使用kafka的经验。

6.1基本的Kafka操作

本节将回顾您将在Kafka集群上执行的最常见操作。 所有在本节中用到的工具都可以在Kafka发行版的bin/目录下找到,如果没有参数就运行,每个工具都会打印所有可能的命令行选项的详细信息。

添加和删除主题

您可以选择手动添加主题,或者在数据首次发布到不存在的主题时自动创建主题。 如果主题是自动创建的,那么您可能需要调整用于自动创建默认主题的主题配置。

使用主题工具添加和修改主题:

bin/kafka-topics.sh –zookeeper zk_host:port/chroot –create –topic my_topic_name
–partitions 20 –replication-factor 3 –config x=y

如:

bin/kafka-topics.sh –create –zookeeper localhost:2181 –replication-factor 1 –partitions 6 –config retention.ms=604800000 –topic xxb_finance_yqzs_etx

复制因子用来控制写入的消息会被多少服务器复制。如果你的复制因子是3,那么如果2个服务器不可用,也不会丢失数据。我们建议你复制因子设置为2或者3,这样在不中断数据消费的情况下,机器可以透明的弹性变化。

分区数量用来控制多少数据日志会被共享。分区数量有几个影响,首先,每个分区必须安装在单独的机器上。因此如果你有20个分区,那么将不超过20台服务器来处理(不计算副本)。最后,分区数量决定了消费者的最大并发数。

每个共享的分区日志都放在kafka日志目录下属于分区自己的文件夹下。这些文件夹名字是由主题名,”-“和分区id组成。因为文件夹名不能超过255个字节,所以主题名也是有限止的。我们假定分区数量不能超过100,000个,那么主题名就不能超过249个,这是为了给”-“(一个字符)和分区id(5个字符 999999)留下足够空间。

命令行中的添加的配置会覆盖服务器中的默认配置。每个主题的完整配置文档3.2节

修改主题

您可以使用相同的主题工具更改主题的配置或分区。

要添加分区,你可以这么做:

bin/kafka-topics.sh –zookeeper zk_host:port/chroot –alter –topic my_topic_name –partitions 40

请注意,分区的一个用例是对数据进行语义分区,并且添加分区不会更改现有数据的分区,因此如果依赖某特定语义分区,则可能会影响消费者。 也就是说,如果数据是通过hash(key)%number_of_partitions进行分区的,那么这个分区可能会因为添加分区而发生shuffled,但Kafka不会尝试以任何方式自动重新分配数据。

添加配置:

bin/kafka-configs.sh –zookeeper zk_host:port/chroot –entity-type topics –entity-name my_topic_name –alter –add-config x=y

删除配置:

bin/kafka-configs.sh –zookeeper zk_host:port/chroot –entity-type topics –entity-name my_topic_name –alter –delete-config x

最后删除一个主题:

bin/kafka-topics.sh –zookeeper zk_host:port/chroot –delete –topic my_topic_name

主题删除选项默认是禁用的。 要启用它,请设置服务器配置

delete.topic.enable=true

Kafka目前不支持减少某个主题的分区数量。

平滑关闭

kafka集群会自动检测broker是否关闭或失效,并且选举新的leader。无论是服务器失效了,还是为了维护或配置故意关闭,都会被kafka集群自动检测。对于后者这种情况(维护或配置),kafka支持一种更平滑的机制来停止一个服务器而不是直接干掉它(kill)。

  • 它将所有日志同步到磁盘,以避免在重新启动时需要进行任何日志恢复(即:检查所有日志尾部的消息的完整性)。日志恢复需要时间,所以这加速了故意的重新启动。
  • 在关闭之前将优先迁移leader服务器上的分区数据,这样会让leader传输的更快,最大限度的减少每个分区不可用的时间到毫秒内。

如果服务是被平滑关闭而不是硬生生的kill,那么同步日志将是自动完成,不过leadership的转移还需要配合一个特殊的设置:

controlled.shutdown.enable=true

注意:如果broker上的所有分区都有副本(即:副本因子大于1,到少一个副本是激活的)平滑关闭才会成功。这可能就是你想要的,因为关闭最后那个副本会导致主题分区不可用(说白了要关闭一个,至少还有一个热备的,否则,只有自己一人,那么自己关闭了,必然导致服务不可用)。

leadership 平衡

只要一个服务器停止或崩溃了,leadership就会转移到分区的其它副本上。即默认情况下,只要broker重启了,它只能当做分区的follower。也就是说它不能被客户端访问用来读写了。

为了避免这种不平衡,kafka有一个首选副本的概念。如果一个分区的副本列表是1,5,9三个节点。那么节点1是leader的首选副本。因为它是最早位于列表中的。你可以通过以下命令让集群重新恢复原有副本为leader.

bin/kafka-preferred-replica-election.sh –zookeeper zk_host:port/chroot

运行这个命令太烦锁,我们可以使用以下配置来让kafka自动平衡:

auto.leader.rebalance.enable=true

通过机架平衡副本

机架感知特性通过不同的机架,扩展了同一分区的不同副本。这把kafka从保证broker失效扩大覆盖到机架故障,限制了一个机架上所有broker一次性全部失效导致数据丢失的风险。(小道消息:此功能是由netflix提供)

你可以通过以下配置,来指定一个broker属于某个特写的机架。

broker.rack=my-rack-id

当一个主题被创建,修改或副本被重新分布,机架约束会被兑现,以确保副本可以跨越多个机架(一个副本到少跨越m个不同的机架,m 由机架数,副本因子确定)。

分配broker副本的算法保证每个broker的leader数量是恒定的,无论broker在机架上如何分布。这保证了吞吐量的均衡。

如果机架上分配不同数量的broker,那么副本分配将不均衡。 具有少量broker的机架将具有更多的副本,意味着他们将使用更多的存储并且向副本中存储更的资源。因此,明智的做法是每个机架配置相同的brokers.

集群间的数据镜像

检查消费者位置

有时,查看消费者位置非常有用。我们有一个工具可以展示一个消费者中的所有消费者位置。

查看一个消费者组名为”my-group” ,主题为”my-topic”的消费者位置,运行工具如下:

bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker –zookeeper localhost:2181 –group test

Group           Topic                          Pid Offset          logSize         Lag             Owner
my-group        my-topic                       0   0               0               0               test_jkreps-mn-1394154511599-60744496-0
my-group        my-topic                       1   0               0               0               test_jkreps-mn-1394154521217-1a0be913-0

从0.9.0版本,kafka.tools.ConsumerOffsetChecker工具已经过时了,请使用kafka.admin.ConsumerGroupCommand(或 bin/kafka-consumer-groups.sh 脚本)

管理消费者组

通过ConsumerGroupCommand工具,我们可以列出,查看描述或删除消费组。 请注意,删除仅在组元数据存储在ZooKeeper中时可用。 当使用新消费API(代理负责分区处理和重新平衡的协调)时,当该组最后提交的偏移量到期时,该组会被删除。 例如,要列出所有主题中的所有消费者组:

bin/kafka-consumer-groups.sh –bootstrap-server broker1:9092 –list

test-consumer-group

要像使用ConsumerOffsetChecker那样查看偏移量,我们可以像这样“描述”消费者组:

bin/kafka-consumer-groups.sh –bootstrap-server broker1:9092 –describe –group test-consumer-group

image

如果您正在使用旧的高级使用者并在ZooKeeper中存储组元数据(即,offsets.storage = zookeeper),请传递–zookeeper而不是bootstrap-server:

bin/kafka-consumer-groups.sh –zookeeper localhost:2181 –list

集群扩展

向kafka集群中添加服务器是容易的,仅仅给他们分配一个唯一的brokerId,并且把这台机器上的kafka启动想来即可。但是这些新服务器不会自动分配任何数据分区。除非新创建主题,或者将数据分区移动到它们上。因此,当你向集群添加一个新的机器时,你可能想把现有的数据迁移一些到这些机器。

新增加了服务器,不影响原有数据,这就不会有新的数据存到新服务器。除非两种情况:把原有分区数据重新分给它,另外,新创建主题。通知情况,新创建主题并不频繁。那么就需要重新分配数据。重新分配数据需要手动启动,而且新的机器也只能做follower。

迁移数据的过程需要手动启动,但是完全自动化执行。迁移过程的低层实现是这样的:kafka增加一个新的服务器,这个新的服务器做为一个分区的follower。允许它完全复制现存的分区数据。当新的服务器完全复制了此分区中的数据后,并且加入了同步副本(in-sync)时,现存副本中的一个就可以删除它们的分区数据了。

分区重新分配工具可用于跨代理移动分区。一个理想的分区分配应该能保证数据负载均衡和分区数量均衡。分区调整工具没有能力智能分调整负载。因此,管理员必须找出哪些主题或分区需要移动。

分区重新分配工具可以运行在3个互斥的模式中:

  • –generate:在此模式下,给定一个主题列表和一个broker列表,工具生成一个重新分配报告(把指定主题的所有分区都移动新有 brokers上)。 此选项仅提供了一种便捷的方式,可以根据主题和目标代理列表生成分区重新分配计划。
  • –execute:在这种模式下,该工具根据用户提供的重新分配计划启动重新分配。 (使用–reassignment-json-file选项指定)。 这可以是由管理员制作的自定义重新分配计划,也可以是使用–generate选项提供的自定义重新分配计划。
  • –verify:在此模式下,该工具会验证上次执行过程中列出的所有分区的重新分配状态。 状态可以是成功完成,失败或正在进行

自动迁移数据到新机器上

重新调整工具可以用来把现有brokers集上的部分主题迁移到新的机器上。当扩展一个存在的集群时,这非常有用。因为很容易把全部主题都移到新的brokers集中,而不是一次只移一个分区。 如果要这么做,我们必须提供一批需要移动的主题列表,和一批新加入的broker列表。工具将均匀的把给定的主题列表中的所有分区移到新的broker集上。迁移过程中,复制因子保持不变。 指定的主题集中的所有分区副本都从旧的brokers集中迁移到新的brokers中。

例如,以下示例将把主题foo1,foo2的所有分区移动到新的代理集5,6。 在本次移动结束时,主题foo1和foo2的所有分区将仅存在于代理5,6上。

因为工具接受json文件格式的参数(包含:需要迁移的主题列表),所以首先创建一个json文件,要把需要迁移的主题配置到文件中

>cat topics-to-move.json

{"topics": [{"topic": "foo1"},
            {"topic": "foo2"}],
"version":1
}

一旦json文件就绪,使用分区重新调整工具生成一个分配计划。

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –topics-to-move-json-file topics-to-move.json –broker-list “5,6” –generate

Current partition replica assignment

{"version":1,
"partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]},
              {"topic":"foo1","partition":0,"replicas":[3,4]},
              {"topic":"foo2","partition":2,"replicas":[1,2]},
              {"topic":"foo2","partition":0,"replicas":[3,4]},
              {"topic":"foo1","partition":1,"replicas":[2,3]},
              {"topic":"foo2","partition":1,"replicas":[2,3]}]
}

Proposed partition reassignment configuration

{"version":1,
"partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]},
              {"topic":"foo1","partition":0,"replicas":[5,6]},
              {"topic":"foo2","partition":2,"replicas":[5,6]},
              {"topic":"foo2","partition":0,"replicas":[5,6]},
              {"topic":"foo1","partition":1,"replicas":[5,6]},
              {"topic":"foo2","partition":1,"replicas":[5,6]}]
}

工具生成了一个把主题foo1,foo2所有分区迁移到brokers 5,6上的计划。注意,分区迁移还没有开始。它只是告诉你当前分配计划和新计划的提议。为了防止万一需要回滚,新的计划应该保存起来。 新的调整计划应该保存成一个json文件(如:expand-cluster-reassignment.json) ,并用–execute选项输入到工具中,如下:

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file expand-cluster-reassignment.json –execute

Current partition replica assignment

{"version":1,
"partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]},
              {"topic":"foo1","partition":0,"replicas":[3,4]},
              {"topic":"foo2","partition":2,"replicas":[1,2]},
              {"topic":"foo2","partition":0,"replicas":[3,4]},
              {"topic":"foo1","partition":1,"replicas":[2,3]},
              {"topic":"foo2","partition":1,"replicas":[2,3]}]
}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions
{"version":1,
"partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]},
              {"topic":"foo1","partition":0,"replicas":[5,6]},
              {"topic":"foo2","partition":2,"replicas":[5,6]},
              {"topic":"foo2","partition":0,"replicas":[5,6]},
              {"topic":"foo1","partition":1,"replicas":[5,6]},
              {"topic":"foo2","partition":1,"replicas":[5,6]}]
}

最后, –verify可以肜来验证重新调整的状态。注意,那个调整计划文件expand-cluster-reassignment.json还要再次使用,如下:

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file expand-cluster-reassignment.json –verify

Status of partition reassignment:
Reassignment of partition [foo1,0] completed successfully
Reassignment of partition [foo1,1] is in progress
Reassignment of partition [foo1,2] is in progress
Reassignment of partition [foo2,0] completed successfully
Reassignment of partition [foo2,1] completed successfully
Reassignment of partition [foo2,2] completed successfully

自定义分区分配和迁移

分区重新分配工具也可用于选择性地将分区的副本移动到特定的一组brokers中。当使用这种方式,它假定用户已经知道重新分配的计划,因此不需要指定一个重新分配计划,也就是跳过–generate步骤,直接执行–execute步骤。

例如:以下例子把foo1主题中的分区0移到 brokers 5,6上,并且把foo2主题中的分区1移到brokers 2,3上。

第一步是手动创建一个json格式的分配计划文件。

>cat custom-reassignment.json

{"version":1,"partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]},{"topic":"foo2","partition":1,"replicas":[2,3]}]}

然后执行:–execute

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file custom-reassignment.json –execute

Current partition replica assignment

{"version":1,
"partitions":[{"topic":"foo1","partition":0,"replicas":[1,2]},
              {"topic":"foo2","partition":1,"replicas":[3,4]}]
}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions
{"version":1,
"partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]},
              {"topic":"foo2","partition":1,"replicas":[2,3]}]
}

执行验证: –verify

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file custom-reassignment.json –verify

Status of partition reassignment:
Reassignment of partition [foo1,0] completed successfully
Reassignment of partition [foo2,1] completed successfully

退役经纪人 Decommissioning brokers

分区重新分配工具没有能力为退役代理自动生成重新分配计划。 因此,管理员必须提出重新分配计划,将代理托管的所有分区的副本移动到其他代理。 这个过程会非常乏味,并且还要保证broker上分区数据不会全部移到同一台机器上。为了让这个过程轻松,我们在未来的版本上增加这样的工具支持。

增加复制因子

增加一个现存分区的复制因子是很容易的。只要在自定义的重新调整分区的json文件中指定一个扩展的副本,并且使用–execute选项就可以增加一个指定分区的复制因子

例如,以下示例将主题foo的分区0的复制因子从1增加到3.在增加复制因子之前,该分区的唯一副本存在于代理5上。作为增加复制因子的一部分,我们将增加更多的副本到broker 6 和7上。

第一步:创建一个重新调整计划文件:

>cat increase-replication-factor.json

{"version":1,
"partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}

使用–execute选项,启动重新分配进程:

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file increase-replication-factor.json –execute

Current partition replica assignment

{"version":1,
"partitions":[{"topic":"foo","partition":0,"replicas":[5]}]}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions
{"version":1,
"partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}

可以使用–verify选项来检查分区重新分配的状态。 请注意,与–verify选项一起使用相同的increase-replication-factor.json(与–execute选项一起使用):

>bin/kafka-reassign-partitions.sh –zookeeper localhost:2181 –reassignment-json-file increase-replication-factor.json –verify

Status of partition reassignment:
Reassignment of partition [foo,0] completed successfully

你也可以使用kafka-topics工具来验证:

>bin/kafka-topics.sh –zookeeper localhost:2181 –topic foo –describe

Topic:foo   PartitionCount:1    ReplicationFactor:3 Configs:
  Topic: foo    Partition: 0    Leader: 5   Replicas: 5,6,7 Isr: 5,6,7

限制数据迁移过程中的带宽使用

配额覆盖在(user, client-id)、用户或客户端级别进行配置的默认值。 默认情况下,客户端收到一个无限制的配额。 可以为每个(user, client-id),用户或client-id group设置自定义配额。

为(user = user1,client-id = clientA)配置自定义配额:

>bin/kafka-configs.sh –zookeeper localhost:2181 –alter –add-config ‘producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200’ –entity-type users –entity-name user1 –entity-type clients –entity-name clientA

Updated config for entity: user-principal 'user1', client-id 'clientA'.

为user=user1配置自定义配额:

>bin/kafka-configs.sh –zookeeper localhost:2181 –alter –add-config ‘producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200’ –entity-type users –entity-name user1

Updated config for entity: user-principal 'user1'.

为client-id = clientA配置自定义配额

>bin/kafka-configs.sh –zookeeper localhost:2181 –alter –add-config ‘producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200’ –entity-type clients –entity-name clientA

Updated config for entity: client-id 'clientA'.

通过指定–entity-default选项而不是–entity-name,可以为每个(user,client-id),user或client-id group设置默认配额。

为user = userA配置默认客户端配额:

>bin/kafka-configs.sh –zookeeper localhost:2181 –alter –add-config ‘producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200’ –entity-type users –entity-name user1 –entity-type clients –entity-default

Updated config for entity: user-principal 'user1', default client-id.
 ```
配置用户的默认配额:

> \>bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' **--entity-type users --entity-default**

Updated config for entity: default user-principal.

配置client-id的默认配额:

> bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' **--entity-type clients --entity-default**

Updated config for entity: default client-id.


以下是如何查看给定(user, client-id)的配额:

> bin/kafka-configs.sh  --zookeeper localhost:2181 --describe **--entity-type users --entity-name user1 --entity-type clients --entity-name clientA**

Configs for user-principal ‘user1’, client-id ‘clientA’ are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200


查看给定用户的配额:

> \>bin/kafka-configs.sh  --zookeeper localhost:2181 **--describe --entity-type users --entity-name user1**

Configs for user-principal ‘user1’ are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200


查看给定client-id的配额:

> \>bin/kafka-configs.sh  --zookeeper localhost:2181 **--describe --entity-type clients --entity-name clientA**

Configs for client-id ‘clientA’ are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200


如果未指定entity-name,则查看指定类型的所有实体。 例如,查看所有用户:

> \>bin/kafka-configs.sh  --zookeeper localhost:2181 **--describe --entity-type users**

Configs for user-principal ‘user1’ are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
Configs for default user-principal are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200


类似的(user, client):

> \>bin/kafka-configs.sh  --zookeeper localhost:2181 **--describe --entity-type users --entity-type clients**

Configs for user-principal ‘user1’, default client-id are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
Configs for user-principal ‘user1’, client-id ‘clientA’ are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200


通过在broker上设置这些配置,可以设置适用于所有客户端ID的默认配额。 这些属性仅在Zookeeper中未配置配额或覆盖默认配置时应用。 默认情况下,每个客户端ID都会收到一个无限制的配额。 以下设置每个生产者和消费者客户端的默认配额为10MB /秒。

**quota.producer.default=10485760**
**quota.consumer.default=10485760**

请注意,这些属性将被弃用,并可能在未来版本中删除。 使用kafka-configs.sh配置的默认值优先于这些属性。

# 6.2数据中心

一些部署可能需要管理一个跨越多个数据中心的数据管道。我们的建议是在每个数据中心本地部署一个kafka集群,每个数据中心的应该只与本地的kafka集群交互。不同数据中心的kafka集群,通过镜像(见集群间的数据镜像 略)实现数据同步。

这种部署方式数据中心做为独立的实体。并允许我们集中管理和调整数据中心之间的复制。这样,即使数据中心之间的链路不可用,每个设备也可以独立运行:当发生这种情况时,镜像会落后,直到链路恢复正常时为止。

对于需要所有数据全局视图的应用,你可使用镜像来提供从所有数据中心聚合好数据的集群。这些聚合的集群用于需要全部数据集合的应用。

这不是唯一的部署方式,因为通过网络,很容易对远程kafka集群进行读写,但是每明显,这会增加请求延迟。

Kafka在生产者和消费者中批量处理数据,所以即使通过高延迟的连接也可以实现高吞吐量。虽然可能需要使用socket.send.buffer.bytes和socket.receive.buffer.bytes配置来增加生产者,消费者和代理的TCP socket buffer大小。

通常不建议通过高延迟链接运行跨越多个数据中心的单个Kafka集群。 这将对Kafka写入和ZooKeeper写入产生非常高的复制延迟,如果位置之间的网络不可用,Kafka和ZooKeeper都不会在所有位置保持可用。

# 6.3 kafka配置

## 重要的客户端配置

Scala生产端的重要配置:

- acks
- compression
- sync vs async production
- batch size (for 异步生产者)

java生产端的重要配置:

- acks
- compression
- batch size
最重要的消费者配置是fetch size。

##生产服务器配置

以下是生产服务器配置示例:

ZooKeeper

zookeeper.connect=[list of ZooKeeper servers]

Log configuration

num.partitions=8
default.replication.factor=3
log.dir=[List of directories. Kafka should have its own dedicated disk(s) or SSD(s).]

Other configurations

broker.id=[An integer. Start with 0 and increment by 1 for each new broker.]
listeners=[list of listeners]
auto.create.topics.enable=false
min.insync.replicas=2
queued.max.requests=[number of concurrent requests]


客户端相关配置不同的用例各不相同。

# 6.4 java版本

从安全角度来看,我们建议您使用JDK 1.8的最新发布版本,因为较早的免费版本已经暴露了安全漏洞。 LinkedIn目前正在使用JDK 1.8 u5运行G1收集器(希望升级到更新的版本)。 如果您决定使用G1收集器(当前的默认值),并且您仍然使用JDK 1.7,请确保您使用的是u51或更新版本。 LinkedIn对u21进行测试,但在该版本中,GC实现方面存在一些问题。 LinkedIn的优化如下:

-Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC
-XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M
-XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80
“`

作为参考,这里是LinkedIn最繁忙的群集(峰值)的统计数据:

  • 60个broker
  • 50k分区(复制因子2)
  • 800k message/s 流入
  • 入站速度为300 MB /秒,出站时为1 GB /秒

优化看起来相当有用,但该集群中的所有broker 90%的GC暂停时间接近21ms,而且他们每秒钟的young GC少于1次。

6.5 硬件和操作系统

我们正在使用有24GB内存的双核四核英特尔至强处理器的机器。

您需要足够的内存来缓存活动的readers and writers。 您可以通过假设希望能够缓冲30秒,并将您的内存需求计算为write_throughput * 30来估计内存需求。

硬盘吞吐量很重要。 我们有8x7200转的SATA硬盘。 一般情况下,硬盘吞吐量是性能瓶颈,更多的硬盘更好。 根据配置刷新行为的方式,您可能会也可能不会从更昂贵的硬盘中受益(如果经常强制刷新,那么更高RPM的SAS驱动器可能会更好)。

硬盘和文件系统

我们建议使用多个硬盘以获得良好的吞吐量,而不是与应用程序日志或其他操作系统文件系统一起存放kafka的数据,以确保很小的延迟。您可以将这些驱动器一起RAID成单个卷或格式,或将每个驱动器配置为自己的目录。由于Kafka具有复制功能,RAID提供的冗余也可以在应用程序级别提供。这个选择有几个折衷。

如果您配置多个数据目录,则会将分区循环分配到配置的数据目录。每个分区将完全位于其中一个数据目录中。如果分区间的数据不均衡,则可能导致磁盘之间的负载不均衡。

RAID可以更好地平衡磁盘之间的负载(尽管似乎并不总是如此),因为它在较低的级别上平衡负载。 RAID的主要缺点是写入吞吐量和降低了可用磁盘空间。

RAID的另一个潜在好处是能够容忍磁盘故障。然而,我们的经验是,重建RAID阵列是/O密集型操作,所以可用性不会有太多的实际改进

应用 vs os刷新管理

Kafka总是立即将所有数据写入文件系统,并支持配置刷新策略的功能,该策略控制何时使用刷新将数据从OS缓存移到磁盘上。可以配置该刷新策略,以在一段时间之后或者在写入一定数量的消息之后强制数据到磁盘。这个配置有几个选择。

kafka最终必须调用fsync才能知道数据已被刷新。从任何未知的fsync’d日志段的崩溃中恢复时,Kafka将通过检查每个消息的CRC来检查其完整性,并在启动时执恢复过程重建相应的偏移量索引文件。

请注意,Kafka中的持久性不需要将同步的将数据写到磁盘,因为失败的节点将始终从其副本中恢复

我们建议完全禁用应用程序fsync的默认刷新设置。这意味着依靠操作系统和Kafka自己的后台刷新功能完成刷新。这为大多数用例提供了最好的选择:无旋钮调节,巨大的吞吐量和延迟,以及完全恢复保证。我们一般认为复制提供的保证比同步到本地磁盘更强,然而偏执狂仍然可能更喜欢同时支持fsync和应用程序级别的策略。

使用应用程序级别刷新设置的缺点是它的磁盘使用模式效率较低(它使操作系统在重新排序时没有什么回旋余地),并且可能会导致延迟,因为大多数Linux文件系统块中的fsync会写入文件,后台刷新做更多的page-level粒度锁定

一般来说,您不需要对文件系统进行任何低级调整,但在接下来的几节中,我们将会介绍其中的一些内容,以防万一。

了解Linux操作系统flush行为

在Linux中,写入文件系统的数据在pagecache中保存,直到必须写入磁盘(由应用程序级fsync或操作系统自己的刷新策略决定)。 数据的刷新是通过一系列叫做pdflush的后台线程来完成的(或者在2.6.32内核中的“刷新线程”)。

Pdflush有一个可配置的策略,用于控制在缓存中可以维护多少脏数据,以及多久必须将数据写回到磁盘。 当Pdflush无法跟上正在写入的数据速率时,最终会使写入过程阻塞导致写入延迟。

您可以通过执行命令来查看OS内存使用情况的当前状态

cat /proc/meminfo

使用页面缓存相对于进程内高速缓存来存储将被写出到磁盘的数据有几个优点:

  • I/O调度程序将连续的小批量转换为更大的物理数据写入,从而提高吞吐量。
  • I/O调度程序将尝试重新排列写入操作,以尽量减少磁盘磁头的移动,从而提高吞吐量。
  • 它会自动使用机器上的所有可用内存

文件系统选择

Kafka使用磁盘上的常规文件,因此它不依赖于特定的文件系统。 然而,使用最多的两个文件系统是EXT4和XFS。 通常,EXT4具有更多的用途,但最近对XFS文件系统的改进已经表明它具有更好的性能,而且不会影响稳定性。

使用各种文件系统创建和安装选项,在具有重要消息的群集上执行比较测试。 kafak监测的主要指标是“Request Local Time”,表示追加操作的时间。 XFS的local times好得多,160ms比250ms +(最好的EXT4配置),以及更低的平均等待时间。 XFS性能也表现更好的稳定性。

。。。略

6.6 监控

Kafka在服务器和Scala客户端使用Yammer Metrics进行度量报告,Java客户端使用Kafka Metrics,这是一个内置的度量标准注册表,最大限度地减少了传递到客户端应用程序的依赖关系。者都通过JMX暴露度量,并且可以配置使用可插拔的统计记录器来报告统计信息,以便连接到您的监控系统。

查看可用指标的最简单方法是启动jconsole并将其指向正在运行的kafka客户端或服务器; 这将允许浏览JMX的所有指标。

我们对以下指标进行图形化和提醒:

6.7 Zookeeper

稳定版

目前最稳定版是3.4,最新版本是3.4.9。zkClient是kafka用于与zookeeper交互的客户端层。

Zookeeper操作

操作上我们通过下面说明安装一个健壮的zookeeper:

  • 物理/硬件/网络冗余布局:不要把它们放在同一个机架上,合适即可(但也不要走极端)。电源和网络有冗余。一个典型的zookeeper应该有5-7个服务器,这样可以容忍2-3台挂掉。当然,如果你有一个小的部署,那么使用3台服务器也是可以接受的。但是要记住,你仅仅能容忍1台服务器挂掉。
  • i/o分离:如果你有一个非常大量的写操作,你可能希望有一组专用的磁盘来记录事务日志。写事务日志是同步的(但是是批量的),因此并行操作可以提高性能。ZooKeeper快照可以是并发写入源,理想情况下应该写在与事务日志分开的磁盘组上。快照是异步写到磁盘的。因此通常可以与操作系统和消息日志文件共享。你可以用dataLogDir参数配置一个服务器独立的磁盘组。
  • 应用隔离:除非你了解别的程序的应用模式,否则不要把别的应用与zookeeper安装在一起。最好把zookeeper单独安装。
  • 使用虚拟机可是可以的,但是具体取决于你的集群布局和读/写模式和SLA,但是虚拟机可能不太稳定。
  • zookeeper配置:使用的是java,因此确保有足够的堆内存(我们通常使用3-5G,不过这要看数据量)。不幸的是,我们没有一个合适的公式。但是要记住,允许更多的ZooKeeper状态意味着快照可能变大,大的快照会影响恢复时间。如果快照变的太大,那么你就需要增initLimit参数的设置,以给服务器足够的时间用来恢复和加入到集群。
  • 监控:JMX和 4lw命令都是非常有用的,他们在某些情况下是重复的(在这种情况下,我们更喜欢4lw,他们更有预见性,至少,他们在监控设施上与LI工作的更好)。
  • 不要过度建设集群,特别是在写入频繁的使用模式下,大型集群意味着大量的集群内通信,

总的来说,我们试图保持zookeeper系统尽可能的小,并且尽可能的简单。与官方发布相比,我们尽量避免对配置或应用程序布局做别的更改,并尽可能保持集群的独立性。所以尽量不要使用内置的版本。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值