云服务器内容精选

  • Kafka性能优化 Kafka性能优化 优化客户端配置 生产者配置建议 可参考配置建议。 消费者配置建议 参数 推荐值 说明 max.poll.records 500 消费者一次能消费到的最大消息数量,默认为500,如果每条消息处理时间较长,建议调小该值,确保在max.poll.interval.ms时间内能完成这一批消息的处理。 max.poll.interval.ms 300000 两次消费拉取请求允许的最大时间间隔,默认为300秒,超过这个时间会认为消费者异常。 fetch.min.bytes 根据业务调整 默认为1,每次FETCH请求最少返回数据量。增加该值可以提高吞吐量,同时也会产生一定延迟。 观测性能指标 Kafka提供了以下性能相关监控指标,从这些指标可以帮助分析消息堆积、分区数据倾斜、流量倾斜等问题。 指标ID 指标名称 指标说明 broker_disk_usage 磁盘容量使用率 该指标为从Kafka节点虚拟机层面采集的磁盘容量使用率。 broker_cpu_core_load CPU核均负载 该指标为从Kafka节点虚拟机层面采集的CPU每个核的平均负载。 broker_memory_usage 内存使用率 该指标为Kafka节点虚拟机层面采集的内存使用率。 broker_cpu_usage CPU使用率 统计Kafka节点虚拟机的CPU使用率。 group_msgs 堆积消息数 该指标用于统计Kafka实例中所有消费组中总堆积消息数。 topic_messages_remained 队列可消费消息数 该指标用于统计消费组指定队列可以消费的消息个数。 broker_messages_in_rate 每秒消息生产速率 统计Kafka节点每秒生产速率。 broker_connections 连接数 统计Kafka节点连接数。 优化数据分区 Kafka将Topic划分为多个分区,所有消息分布式存储在各个分区上。每个分区有一个或多个副本,分布在不同的Broker节点上,每个副本存储一份全量数据,副本之间的消息数据保持同步。Kafka的Topic、分区、副本和代理的关系如下图所示: 在实际业务过程中可能会遇到各节点间或分区之间业务数据不均衡的情况,业务数据不均衡会降低Kafka集群的性能,降低资源使用率。 业务数据不均衡原因 业务中部分Topic的流量远大于其他Topic,会导致节点间的数据不均衡。 生产者发送消息时指定了分区,未指定的分区没有消息,会导致分区间的数据不均衡。 生产者发送消息时指定了消息Key,按照对应的Key发送消息至对应的分区,会导致分区间的数据不均衡。 系统重新实现了分区分配策略,但策略逻辑有问题,会导致分区间的数据不均衡。 Kafka扩容了Broker节点,新增的节点没有分配分区,会导致节点间的数据不均衡。 业务使用过程中随着集群状态的变化,多少会发生一些Leader副本的切换或迁移,会导致个别Broker节点上的数据更多,从而导致节点间的数据不均衡 使用数据压缩 在客户端CPU资源情况可控的情况下,使用压缩算法对数据进行压缩。 常用的压缩算法包括:ZIP,GZIP,SNAPPY,LZ4等。选择压缩算法时,需考虑数据的压缩率和压缩耗时。通常压缩率越高的算法,压缩耗时也越高。 压缩方式 压缩比 客户端CPU占用 服务端CPU占用 磁盘占用 broker带宽占用 gzip 中 中 低 中 低 lz4 中 中 中 中 中 zstd 高 中 低 低 低 snappy 低 高 高 高 高 如果追求高TPS,建议采用lz4压缩算法;如果追求较低的网络I/O或希望较低的客户端/服务端CPU占用,建议采用zstd压缩算法。这里通常推荐使用lz4压缩算法,同时不建议使用gzip算法,因为它会是一种计算敏感的压缩算法。同时针对一批数据(batch)消息压缩,更好的运用批处理可以获得更高的TPS。 父主题: 消息队列性能优化
  • RabbitMQ性能优化 保持尽可能短的队列长度 太多的消息堆积在队列中会造成内存负载过高,为了释放内存,RabbitMQ 会把消息转存到磁盘,转存过程会耗费大量时间,造成消息处理速度下降或直接阻塞生产流程。因此队列中堆积过多的消息容易对 broker 产生负面效应。除此之外,如果节点崩溃后重启,过多的数据会使得重建索引需要消耗大量时间,集群模式下的节点间同步数据也会非常耗时。 使用惰性队列提升稳定性 惰性队列(lazy queues)是 RabbitMQ 3.6 之后新增的特性。惰性队列的消息会自动存储到磁盘,因此减少了内存的使用率,但是会增加I/O开销,影响吞吐量。使用惰性队列能够更好的把控性能,并且使得集群更加的稳定。和非惰性队列不同,消息不会积累在内存中然后等到内存不足再一次性刷到磁盘,造成队列性能不稳定。如果你需要一次发送大量消息,或者消费速度长时间赶不上生产速度,那么我们推荐使用惰性队列。 请注意,以下情况不建议使用惰性队列: a. 追求高性能 b. 队列无明显积压 c. 队列设置了 max-length 策略 通过TTL或者max-length限制队列长度 可以通过设置消息 TTL、队列 TTL 和 max-length 来限制队列长度。如果队列长度达到 max-length 值,队列头部的消息会被丢弃或进入死信队列。消息的生存时间到期也会被丢弃或者进入死信队列。 关注队列个数 在 RabbitMQ 中,一条队列是由一个线程处理的。利用服务器的多核特性和分布式特性建立多条队列,将不同队列分布到不同 CPU 或不同节点,以此来获取高吞吐量。同时需要注意,过多的队列可能会对 CPU 和内存造成较高的负担,RabbitMQ management 接口的响应速度也会受到影响。 自动为临时队列分配队列名 如果使用临时队列(包括排他队列、自动删除队列、非持久化队列),可以调用不带参数的接口queueDeclare()让 RabbitMQ 自动为你分配一个队列名。 根据需要使用自动删除队列 如果不再使用的队列资源长期保存在服务端,可能对 RabbitMQ 性能造成影响,可以通过三种方法自动地删除队列:为队列设置 TTL 属性、为队列设置 auto-delete 属性、为队列设置 exclusive 属性。 控制优先级队列的使用 每一个优先级会在Erlang VM中使用一个内部队列,这会消耗一定的资源。大多数场景下,使用最多5个优先级就够了。 如何确定消息大小 如何选择发往RabbitMQ的消息长度是一个常见问题。记住,每秒钟发送的消息数比消息大小更容易达到瓶颈。虽然发送大消息不是一个好的做法,但是发送多条小的消息也可能不是一个好的选择。更好的方法是生产者把多条小消息封装成一条大消息,然后由消费者来拆开处理。然而,如果一条大消息封装了太多的子消息,处理速度将会受到影响。如果一条子消息处理失败,整个大消息都需要重传。因此,当选择消息大小时,需要考虑带宽和业务架构。 连接和通道 每条连接(connection)大约占用 100KB 内存(启动 TLS 则会占用更多)。数以千计的连接会对 RabbitMQ 服务端造成较大的负担,极端情况下会因为 OOM 而崩溃。AMQP 协议可以在单条 TCP 连接上进行多路复用。建议一个进程只创建一条 TCP 连接,每个线程复用这条连接创建各自的通道(channel)。连接应该保持长生命周期,因为 AMQP 建立连接需要一定的开销(至少 7 个 TCP 包)。相反,通道则允许较为频繁的开启和关闭,但在发布消息时复用通道也是一个好的习惯,不要每发送一条消息都开启一个新的通道。同时需要注意如下几点: 多线程不要共享通道,因为你很难实现线程安全。 不要频繁的开启或关闭连接和通道,否则会造成更高的延迟。 生产者和消费者使用独立的连接,来提高吞吐量。 大量的连接和通道可能会影响管理接口的性能,造成请求超时。 消息确认 消费者使用确认(Acknowledgment)机制避免消息因为连接问题而丢失,客户端可以在收到消息或者处理完消息后回给服务端一个 ack 消息。消费者确认机制会对性能造成影响,如果单纯追求高吞吐量,应该关闭手动确认功能。如果消息对于业务来说比较重要,那么应该在消息被处理完之后才确认该条消息。生产者使用 Confirm 机制来实现类似的功能,当服务端收到生产者发来的消息,它会返回一个 ack 消息,以此来实现最少一次(at-least-once)的投递语义。注意,Confirm 机制同样会影响性能。 控制未确认消息个数 所有未确认的消息都会暂存在内存中,太多的未确认消息可能造成服务 OOM。为了限制未确认消息的规模,你可以在消费者端开启prefetch功能来限制消息拉取上限。 持久化资源 为了防止因为服务宕机、重启、硬件问题等原因造成的消息丢失,请使用持久化队列和消息。持久化消息涉及到写磁盘操作,如果使用了惰性队列也会将所有消息写入磁盘,包括非持久化消息。如果单纯追求高性能,可以使用非持久化消息。 开启TLS连接 你可以在 AMQP 之上使用 TLS 连接 RabbitMQ。因为数据需要加解密,所以 TLS 对性能有一定的影响。 如何正确选择 QoS 值 如果只有单个或少量消费者,并且消费速度很快,那么建议 QoS 设置的大一点,使得客户端保持忙碌状态。 如果客户端的消息处理速度和带宽保持不变,简单的用公式RTT / 单条消息处理时间就可以估算出应该设置多大的 QoS 值。 如果消费者数量较多并且消息处理速度较快,那么建议 QoS 设置的小一点。 如果消费者数量较多并且消息处理速度较慢,那么建议 QoS 设置为 1,让消息平均的分发到所有消费者。 请注意,如果客户端使用拉模式或者开启了自动确认(auto-ack),预拉取功能将会失效。一个常见的错误是不限制预拉取消息个数,所有消息全部发送给一个消费者,造成消费者 OOM 崩溃和消息重复投递。更多关于 RabbitMQ 预拉取功能的信息可以参考这里。 观测性能指标 指标ID 指标名称 指标说明 channels 通道数 该指标用于统计RabbitMQ实例中的总通道数。 queues 队列数 该指标用于统计RabbitMQ实例中的总队列数。 connections 连接数 该指标用于统计RabbitMQ实例中的总连接数。 connections_usage 连接数使用率 当前节点实际连接数占最大连接数比率。 rabbitmq_disk_usage 磁盘容量使用率 统计Rabbitmq节点虚拟机的磁盘容量使用率。 rabbitmq_cpu_usage CPU使用率 统计Rabbitmq节点虚拟机的CPU使用率。 rabbitmq_memory_usage 内存使用率 统计Rabbitmq节点虚拟机的内存使用率。 rabbitmq_cpu_core_load CPU核均负载 统计Rabbitmq节点虚拟机CPU每个核的平均负载。 全量指标可参考RabbitMQ支持的监控指标。 父主题: 消息队列性能优化