Kafka在提高效率方面做了很大努力。Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作。读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也尽量使读的操作更轻量化。

我们之前讨论了磁盘的性能问题,线性读写的情况下影响磁盘性能问题大约有两个方面:太多的琐碎的I/O操作和太多的字节拷贝。I/O问题发生在客户端和服务端之间,也发生在服务端内部的持久化的操作中。
消息集(message set)
为了避免这些问题,Kafka建立了“消息集(message set)”的概念,将消息组织到一起,作为处理的单位。以消息集为单位处理消息,比以单个的消息为单位处理,会提升不少性能。Producer把消息集一块发送给服务端,而不是一条条的发送;服务端把消息集一次性的追加到日志文件中,这样减少了琐碎的I/O操作。consumer也可以一次性的请求一个消息集。
另外一个性能优化是在字节拷贝方面。在低负载的情况下这不是问题,但是在高负载的情况下它的影响还是很大的。为了避免这个问题,Kafka使用了标准的二进制消息格式,这个格式可以在producer,broker和producer之间共享而无需做任何改动。
zero copy
Broker维护的消息日志仅仅是一些目录文件,消息集以固定队的格式写入到日志文件中,这个格式producer和consumer是共享的,这使得Kafka可以一个很重要的点进行优化:消息在网络上的传递。现代的unix操作系统提供了高性能的将数据从页面缓存发送到socket的系统函数,在linux中,这个函数是sendfile.
为了更好的理解sendfile的好处,我们先来看下一般将数据从文件发送到socket的数据流向:

  1. 操作系统把数据从文件拷贝内核中的页缓存中
  2. 应用程序从页缓存从把数据拷贝自己的内存缓存中
  3. 应用程序将数据写入到内核中socket缓存中
  4. 操作系统把数据从socket缓存中拷贝到网卡接口缓存,从这里发送到网络上。

这显然是低效率的,有4次拷贝和2次系统调用。Sendfile通过直接将数据从页面缓存发送网卡接口缓存,避免了重复拷贝,大大的优化了性能。
在一个多consumers的场景里,数据仅仅被拷贝到页面缓存一次而不是每次消费消息的时候都重复的进行拷贝。这使得消息以近乎网络带宽的速率发送出去。这样在磁盘层面你几乎看不到任何的读操作,因为数据都是从页面缓存中直接发送到网络上去了。
这篇文章详细介绍了sendfile和zero-copy技术在Java方面的应用。
数据压缩
很多时候,性能的瓶颈并非CPU或者硬盘而是网络带宽,对于需要在数据中心之间传送大量数据的应用更是如此。当然用户可以在没有Kafka支持的情况下各自压缩自己的消息,但是这将导致较低的压缩率,因为相比于将消息单独压缩,将大量文件压缩在一起才能起到最好的压缩效果。
Kafka采用了端到端的压缩:因为有“消息集”的概念,客户端的消息可以一起被压缩后送到服务端,并以压缩后的格式写入日志文件,以压缩的格式发送到consumer,消息从producer发出到consumer拿到都被是压缩的,只有在consumer使用的时候才被解压缩,所以叫做“端到端的压缩”。
Kafka支持GZIP和Snappy压缩协议。更详细的内容可以查看这里

漫游Kafka设计篇之性能优化(7)的更多相关文章

  1. 漫游Kafka设计篇之性能优化

    Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...

  2. 漫游Kafka设计篇之数据持久化

    Kafka大量依赖文件系统去存储和缓存消息.对于硬盘有个传统的观念是硬盘总是很慢,这使很多人怀疑基于文件系统的架构能否提供优异的性能.实际上硬盘的快慢完全取决于使用它的方式.设计良好的硬盘架构可以和内 ...

  3. 漫游Kafka设计篇之主从同步

    Kafka允许topic的分区拥有若干副本,这个数量是可以配置的,你可以为每个topci配置副本的数量.Kafka会自动在每个个副本上备份数据,所以当一个节点down掉时数据依然是可用的. Kafka ...

  4. 漫游Kafka设计篇之Producer和Consumer

    Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...

  5. 漫游Kafka设计篇之Producer和Consumer(4)

    Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...

  6. 漫游Kafka设计篇之消息传输的事务定义

    之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...

  7. 漫游Kafka设计篇之消息传输的事务定义(5)

    之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...

  8. HBase设计与开发性能优化(转)

    本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,这里涉及的不多,这部分可以参考:淘宝Ken Wu同学的博客. 1. 表的设计 1.1 Pr ...

  9. 正式学习 React(三)番外篇 reactjs性能优化之shouldComponentUpdate

    性能优化 每当开发者选择将React用在真实项目中时都会先问一个问题:使用react是否会让项目速度更快,更灵活,更容易维护.此外每次状态数据发生改变时都会进行重新渲染界面的处理做法会不会造成性能瓶颈 ...

随机推荐

  1. javascript 异常基本语法

    http://www.w3school.com.cn/js/js_onerror.asp try...catch 的作用是测试代码中的错误.   JavaScript - 捕获错误 当我们在网上冲浪时 ...

  2. mysql拼接字符串和过滤字符的方法

    数据 id                value 1        aa<p>QL实木颗粒</p> 2        bb<p>QL实木颗粒</p> ...

  3. Mosquitto----服务器日志

    客户端连接日志 1403334375: New connection from 121.201.8.163 on port 1883. 1403334375: New client connected ...

  4. c# ComboBox绑定枚举

    定义枚举 public enum UserLevel { Commmon = , Administrator, Developer } 方法一 private void Method1() { com ...

  5. Mysql 创建表和删除表

    在数据库中创建一张表的基本语法如下: CREATE TABLE tablename (column_name_1 column_type_1 constraints, column_name_2 co ...

  6. spring in action 7.1 小结

    0 AbstractAnnotationConfigDispatcherServletInitializer剖析,在Servlet 3.0环境中,容器会在类路径中查找实现ServletContaine ...

  7. jsp常用标签和标签库及javaBean规范

    1 常用标签forward,pararm,include <jsp:forward page=""></jsp:forward> <jsp:param ...

  8. Node.js验证码模块captchapng

    captchapng是一个基于pnglib模块开发,数字型验证码模块.内置字体.全JavaScript无其它依赖.不像有的验证码需要依赖canvas或者是需要编译,而且captchapng使用起来简单 ...

  9. angularjs 构建主页 内置过滤器、日期的格式化

    从构建负责管理主屏幕的 MainController 开始.在这个 MainController 控制器内,只需设置一个每秒运转一次,同时更新一个局部作用域变量的延时 angular.module(' ...

  10. 解决The markup in the document following the root element must be well-formed.

    出现问题的代码: <security-constraint> <web-resource-collection> <web-resource-name>Regist ...