RocketMQ 为什么这么快?我从源代码中找出了十大原因!
大家好,我是三友~~
RocketMQ作为阿里开源的消息中间件,深受广大开发者的喜爱
而这其中一个很重要原因就是,它处理消息和拉取消息的速度非常快
那么,问题来了,RocketMQ为什么这么快呢?
接下来,我将从以下10个方面来探讨一下RocketMQ这么快的背后原因
如果你对RocketMQ还不了解,可以从公众号后台菜单栏中查看我之前写的关于RocketMQ的几篇文章
如果你对RocketMQ源码也感兴趣,可以从下面这个仓库fork一下源码,我在源码中加了中文注释,并且后面我还会持续更新注释
https://github.com/sanyou3/rocketmq.git
本文是基于RocketMQ 4.9.x版本讲解
批量发送消息
RocketMQ在发送消息的时候支持一次性批量发送多条消息,如下代码所示:
public class Producer {
public static void main(String[] args) throws Exception {
//创建一个生产者,指定生产者组为 sanyouProducer
DefaultMQProducer producer = new DefaultMQProducer("sanyouProducer");
// 指定NameServer的地址
producer.setNamesrvAddr("192.168.200.143:9876");
// 启动生产者
producer.start();
//用以及集合保存多个消息
List<Message> messages = new ArrayList<>();
messages.add(new Message("sanyouTopic", "三友的java日记 0".getBytes()));
messages.add(new Message("sanyouTopic", "三友的java日记 1".getBytes()));
messages.add(new Message("sanyouTopic", "三友的java日记 2".getBytes()));
// 发送消息并得到消息的发送结果,然后打印
SendResult sendResult = producer.send(messages);
System.out.printf("%s%n", sendResult);
// 关闭生产者
producer.shutdown();
}
}
通过批量发送消息,减少了RocketMQ客户端与服务端,也就是Broker之间的网络通信次数,提高传输效率
不过在使用批量消息的时候,需要注意以下三点:
- 每条消息的Topic必须都得是一样的
- 不支持延迟消息和事务消息
- 不论是普通消息还是批量消息,总大小默认不能超过4m
消息压缩
RocketMQ在发送消息的时候,当发现消息的大小超过4k的时候,就会对消息进行压缩
这是因为如果消息过大,会对网络带宽造成压力
不过需要注意的是,如果是批量消息的话,就不会进行压缩,如下所示:
压缩消息除了能够减少网络带宽造成压力之外,还能够节省消息存储空间
RocketMQ在往磁盘存消息的时候,并不会去解压消息,而是直接将压缩后的消息存到磁盘
消费者拉取到的消息其实也是压缩后的消息
不过消费者在拿到消息之后会对消息进行解压缩
当我们的业务系统拿到消息的时候,其实就是解压缩后的消息
虽然压缩消息能够减少带宽压力和磁盘存储压力
但是由于压缩和解压缩的过程都是在客户端(生产者、消费者)完成的
所以就会导致客户端消耗更多的CPU资源,对CPU造成一定的压力
高性能网络通信模型
当生产者处理好消息之后,就会将消息通过网络通信发送给服务端
而RocketMQ之所以快的一个非常重要原因就是它拥有高性能网络通信模型
RocketMQ网络通信这块底层是基于Netty来实现的
Netty是一款非常强大、非常优秀的网络应用程序框架,主要有以下几个优点:
- 异步和事件驱动:Netty基于事件驱动的架构,使用了异步I/O操作,避免了阻塞式I/O调用的缺陷,能够更有效地利用系统资源,提高并发处理能力。
- 高性能:Netty针对性能进行了优化,比如使用直接内存进行缓冲,减少垃圾回收的压力和内存拷贝的开销,提供了高吞吐量、低延迟的网络通讯能力。
- 可扩展性:Netty的设计允许用户自定义各种Handler来处理协议编码、协议解码和业务逻辑等。并且,它的模块可插拔性设计使得用户可以根据需要轻松地添加或更换组件。
- 简化API:与Java原生NIO库相比,Netty提供了更加简洁易用的API,大大降低了网络编程的复杂度。
- 安全:Netty内置了对SSL/TLS协议的支持,使得构建安全通信应用变得容易。
- 丰富的协议支持:Netty提供了HTTP、HTTP/2、WebSocket、Google Protocol Buffers等多种协议的编解码支持,满足不同网络应用需求。
- ...
就是因为Netty如此的强大,所以不仅仅RocketMQ是基于Netty实现网络通信的
几乎绝大多数只要涉及到网络通信的Java类框架,底层都离不开Netty的身影
比如知名RPC框架Dubbo、Java gRPC实现、Redis的亲儿子Redisson、分布式任务调度平台xxl-job等等
它们底层在实现网络通信时,都是基于Netty框架
零拷贝技术
当消息达到RocketMQ服务端之后,为了能够保证服务端重启之后消息也不丢失,此时就需要将消息持久化到磁盘
由于涉及到消息持久化操作,就涉及到磁盘文件的读写操作
RocketMQ为了保证磁盘文件的高性能读写,使用到了一个叫零拷贝的技术
1、传统IO读写方式
说零拷贝之前,先说一下传统的IO读写方式。
比如现在有一个需求,将磁盘文件通过网络传输出去
那么整个传统的IO读写模型如下图所示
传统的IO读写其实就是read + write的操作,整个过程会分为如下几步
- 用户调用read()方法,开始读取数据,此时发生一次上下文从用户态到内核态的切换,也就是图示的切换1
- 将磁盘数据通过DMA拷贝到内核缓存区
- 将内核缓存区的数据拷贝到用户缓冲区,这样用户,也就是我们写的代码就能拿到文件的数据
- read()方法返回,此时就会从内核态切换到用户态,也就是图示的切换2
- 当我们拿到数据之后,就可以调用write()方法,此时上下文会从用户态切换到内核态,即图示切换3
- CPU将用户缓冲区的数据拷贝到Socket缓冲区
- 将Socket缓冲区数据拷贝至网卡
- write()方法返回,上下文重新从内核态切换到用户态,即图示切换4
整个过程发生了4次上下文切换和4次数据的拷贝,这在高并发场景下肯定会严重影响读写性能。
所以为了减少上下文切换次数和数据拷贝次数,就引入了零拷贝技术。
2、零拷贝
零拷贝技术是一个思想,指的是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域。
实现零拷贝的有以下两种方式:
- mmap()
- sendfile()
mmap()
mmap(memory map)是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
简单地说就是内核缓冲区和应用缓冲区进行映射
用户在操作应用缓冲区时就好像在操作内核缓冲区
比如你往应用缓冲区写数据,就好像直接往内核缓冲区写数据,这个过程不涉及到CPU拷贝
而传统IO就需要将在写完应用缓冲区之后需要将数据通过CPU拷贝到内核缓冲区
同样地上述文件传输功能,如果使用mmap的话,由于我们可以直接操作内核缓冲区
此时我们就可以将内核缓冲区的数据直接CPU拷贝到Socket缓冲区
整个IO模型就会如下图所示:
基于mmap IO读写其实就变成mmap + write的操作,也就是用mmap替代传统IO中的read操作
- 当用户发起mmap调用的时候会发生上下文切换1,进行内存映射,然后数据被拷贝到内核缓冲区,mmap返回,发生上下文切换2
- 随后用户调用write,发生上下文切换3,将内核缓冲区的数据拷贝到Socket缓冲区,write返回,发生上下文切换4。
上下文切换的次数仍然是4次,但是拷贝次数只有3次,少了一次CPU拷贝。
所以总的来说,使用mmap就可以直接少一次CPU拷贝。
说了这么多,那么在Java中,如何去实现mmap,也就是内核缓冲区和应用缓冲区映射呢?
其实在Java NIO类库中就提供了相应的API,当然底层也还是调用Linux系统的mmap()实现的,代码如下所示
FileChannel fileChannel = new RandomAccessFile("test.txt", "rw").getChannel();
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size());
MappedByteBuffer,你可以认为操作这个对象就好像直接操作内核缓冲区
比如可以通过MappedByteBuffer读写磁盘文件,此时就好像直接从内核缓冲区读写数据
当然也可以直接通过MappedByteBuffer将文件的数据拷贝到Socket缓冲区,实现上述文件传输的模型
这里我就不贴相应的代码了
RocketMQ在存储文件时,就是通过mmap技术来实现高效的文件读写
RocketMQ中使用mmap代码
虽然前面一直说mmap不涉及CPU拷贝,但在某些特定场景下,尤其是在写操作或特定的系统优化策略下,还是可能涉及CPU拷贝。
sendfile()
sendfile()跟mmap()一样,也会减少一次CPU拷贝,但是它同时也会减少两次上下文切换。
sendfile()主要是用于文件传输,比如将文件传输到另一个文件,又或者是网络
当基于sendfile()时,一次文件传输的过程就如下图所示:
用户发起sendfile()调用时会发生切换1,之后数据通过DMA拷贝到内核缓冲区,之后再将内核缓冲区的数据CPU拷贝到Socket缓冲区,最后拷贝到网卡,sendfile()返回,发生切换2。
同样地,Java NIO类库中也提供了相应的API实现sendfile
当然底层还是操作系统的sendfile()
FileChannel channel = FileChannel.open(Paths.get("./test.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
//调用transferTo方法向目标数据传输
channel.transferTo(position, len, target);
FileChannel的transferTo方法底层就是基于sendfile来的
在如上代码中,并没有文件的读写操作,而是直接将文件的数据传输到target目标缓冲区
也就是说,sendfile传输文件时是无法知道文件的具体的数据的
但是mmap不一样,mmap可以来直接修改内核缓冲区的数据
假设如果需要对文件的内容进行修改之后再传输,mmap可以满足
小总结
在传统IO中,如果想将用户缓存区的数据放到内核缓冲区,需要经过CPU拷贝
而基于零拷贝技术可以减少CPU拷贝次数,常见的有两种:
- mmap()
- sendfile()
mmap()是将用户缓冲区和内核缓冲区共享,操作用户缓冲区就好像直接操作内核缓冲区,读写数据时不需要CPU拷贝
Java中可以使用MappedByteBuffer这个API来达到操作内核缓冲区的效果
sendfile()主要是用于文件传输,可以通过sendfile()将一个文件内容传输到另一个文件中或者是网络中
sendfile()在整个过程中是无法对文件内容进行修改的,如果想修改之后再传输,可以通过mmap来修改内容之后再传输
上面出现的API都是Java NIO标准类库中的
如果你看的还是很迷糊,那直接记住一个结论
之所以基于零拷贝技术能够高效的实现文件的读写操作,主要因为是减少了CPU拷贝次数和上下文切换次数
在RocketMQ中,底层是基于mmap()来实现文件的高效读写的
顺序写
RocketMQ在存储消息时,除了使用零拷贝技术来实现文件的高效读写之外
还使用顺序写的方式提高数据写入的速度
RocketMQ会将消息按照顺序一条一条地写入文件中
这种顺序写的方式由于减少了磁头的移动和寻道时间,在大规模数据写入的场景下,使得数据写入的速度更快
高效的数据存储结构
Topic和队列的关系
在RocketMQ中,默认会为每个Topic在每个服务端Broker实例上创建4个队列
如果有两个Broker,那么默认就会有8个队列
每个Broker上的队列上的编号(queueId)都是从0开始
CommitLog
前面一直说,当消息到达RocektMQ服务端时,需要将消息存到磁盘文件
RocketMQ给这个存消息的文件起了一个高大上的名字:CommitLog
由于消息会很多,所以为了防止文件过大,CommitLog在物理磁盘文件上被分为多个磁盘文件,每个文件默认的固定大小是1G
消息在写入到文件时,除了包含消息本身的内容数据,也还会包含其它信息,比如
- 消息的Topic
- 消息所在队列的id,生产者发送消息时会携带这个队列id
- 消息生产者的ip和端口
- ...
这些数据会和消息本身按照一定的顺序同时写到CommitLog文件中
上图中黄色排列顺序和实际的存的内容并非实际情况,我只是举个例子
ConsumeQueue
除了CommitLog文件之外,RocketMQ还会为每个队列创建一个磁盘文件
RocketMQ给这个文件也起了一个高大上的名字:ConsumeQueue
当消息被存到CommitLog之后,其实还会往这条消息所在队列的ConsumeQueue文件中插一条数据
每个队列的ConsumeQueue也是由多个文件组成,每个文件默认是存30万条数据
插入ConsumeQueue中的每条数据由20个字节组成,包含3部分信息
- 消息在CommitLog的起始位置(8个字节),也被称为偏移量
- 消息在CommitLog存储的长度(4个字节)
- 消息tag的hashCode(8个字节)
每条数据也有自己的编号(offset),默认从0开始,依次递增
所以,通过ConsumeQueue中存的数据可以从CommitLog中找到对应的消息
那么这个ConsumeQueue有什么作用呢?
其实通过名字也能猜到,这其实跟消息消费有关
当消费者拉取消息的时候,会告诉服务端四个比较重要的信息
- 自己需要拉取哪个Topic的消息
- 从Topic中的哪个队列(queueId)拉取
- 从队列的哪个位置(offset)拉取消息
- 拉取多少条消息(默认32条)
服务端接收到消息之后,总共分为四步处理:
- 首先会找到对应的Topic
- 之后根据queueId找到对应的ConsumeQueue文件
- 然后根据offset位置,从ConsumeQueue中读取跟拉取消息条数一样条数的数据
由于ConsumeQueue每条数据都是20个字节,所以根据offset的位置可以很快定位到应该从文件的哪个位置开始读取数据
- 最后解析每条数据,根据偏移量和消息的长度到CommitLog文件查找真正的消息内容
整个过程如下图所示:
所以,从这可以看出,当消费者在拉取消息时,ConsumeQueue其实就相当于是一个索引文件,方便快速查找在CommitLog中的消息
并且无论CommitLog存多少消息,整个查找消息的时间复杂度都是O(1)
由于ConsumeQueue每条数据都是20个字节,所以如果需要找第n条数据,只需要从第n * 20个字节的位置开始读20个字节的数据即可,这个过程是O(1)的
当从ConsumeQueue找到数据之后,解析出消息在CommitLog存储的起始位置和大小,之后就直接根据这两个信息就可以从CommitLog中找到这条消息了,这个过程也是O(1)的
所以整个查找消息的过程就是O(1)的
所以从这就可以看出,ConsumeQueue和CommitLog相互配合,就能保证快速查找到消息,消费者从而就可以快速拉取消息
异步处理
RocketMQ在处理消息时,有很多异步操作,这里我举两个例子:
- 异步刷盘
- 异步主从复制
异步刷盘
前面说到,文件的内容都是先写到内核缓冲区,也可以说是PageCache
而写到PageCache并不能保证消息一定不丢失
因为如果服务器挂了,这部分数据还是可能会丢失的
所以为了解决这个问题,RocketMQ会开启一个后台线程
这个后台线程默认每隔0.5s会将消息从PageCache刷到磁盘中
这样就能保证消息真正的持久化到磁盘中
异步主从复制
在RocketMQ中,支持主从复制的集群模式
这种模式下,写消息都是写入到主节点,读消息一般也是从主节点读,但是有些情况下可能会从从节点读
从节点在启动的时候会跟主节点建立网络连接
当主节点将消息存储的CommitLog文件之后,会通过后台一个异步线程,不停地将消息发送给从节点
从节点接收到消息之后,就直接将消息存到CommitLog文件
小总结
就是因为有这些异步操作,大大提高了消息存储的效率
不过值得注意的,尽管异步可以提高效率,但是也增加了不确定性,比如丢消息等等
当然RocketMQ也支持同步等待消息刷盘和主从复制成功,但这肯定会导致性能降低
所以在项目中可以根据自己的业务需要选择对应的刷盘和主从复制的策略
批量处理
除了异步之外,RocketMQ还大量使用了批量处理机制
比如前面说过,消费者拉取消息的时候,可以指定拉取拉取消息的条数,批量拉取消息
这种批量拉取机制可以减少消费者跟RocketMQ服务端的网络通信次数,提高效率
除了批量拉取消息之外,RocketMQ在提交消费进度的时候也使用了批量处理机制
所谓的提交消费进度就是指
当消费者在成功消费消息之后,需要将所消费消息的offset(ConsumeQueue中的offset)提交给RocketMQ服务端
告诉RocketMQ,这个Queue的消息我已经消费到了这个位置了
这样一旦消费者重启了或者其它啥的要从这个Queue重新开始拉取消息的时候
此时他只需要问问RocketMQ服务端上次这个Queue消息消费到哪个位置了
之后消费者只需要从这个位置开始消费消息就行了,这样就解决了接着消费的问题
RocketMQ在提交消费进度的时候并不是说每消费一条消息就提交一下这条消息对应的offset
而是默认每隔5s定时去批量提交一次这5s钟消费消息的offset
锁优化
由于RocketMQ内部采用了很多线程异步处理机制
这就一定会产生并发情况下的线程安全问题
在这种情况下,RocketMQ进行了多方面的锁优化以提高性能和并发能力
就比如拿消息存储来说
为了保证消息是按照顺序一条一条地写入到CommitLog文件中,就需要对这个写消息的操作进行加锁
而RocketMQ默认使用ReentrantLock来加锁,并不是synchronized
当然除了默认情况外,RocketMQ还提供了一种基于CAS加锁的实现
这种实现可以在写消息压力较低的情况下使用
当然除了写消息之外,在一些其它的地方,RocketMQ也使用了基于CAS的原子操作来代替传统的锁机制
例如使用大量使用了AtomicInteger、AtomicLong等原子类来实现并发控制,避免了显式的锁竞争,提高了性能
线程池隔离
RocketMQ在处理请求的时候,会为不同的请求分配不同的线程池进行处理
比如对于消息存储请求和拉取消息请求来说
Broker会有专门为它们分配两个不同的线程池去分别处理这些请求
这种让不同的业务由不同的线程池去处理的方式,能够有效地隔离不同业务逻辑之间的线程资源的影响
比如消息存储请求处理过慢并不会影响处理拉取消息请求
所以RocketMQ通过线程隔离及时可以有效地提高系统的并发性能和稳定性
总结
到这我就从10个方面讲完了RocketMQ为什么这么快背后的原因
不知道你读完文章之后有什么感受
其实实际上RocketMQ快的原因远远不止我上面说的这几点
RocketMQ本身还做了很多其它的优化,比如拉取消息的长轮询机制、文件预热机制等等
正是因为有各种各样设计细节上的优化,才最终决定了RocketMQ出色的性能表现
好了,本文就讲到这里,如果觉得本文对你有点帮助,欢迎点赞、在看、收藏、转发分享给其他需要的人
你的支持就是我更新的最大动力,感谢感谢!
让我们下期再见,拜拜!
参考:
1、https://mp.weixin.qq.com/s/mOD9Z6pxSxBQuNx3YaUw3A
推荐阅读
-
aps是什么意思_不同的富士APS-C画幅微单区别在哪里,档次是怎么划分的?-X-A系列原本指的是富士的入门级微单,最大的特点是没有使用富士X-Trans™CMOS 传感器,目前在售的有两款,分别是XA5和XA7。 富士(FUJIFILM)X-A5/XA5 15-45套机 富士(FUJIFILM)X-A7/XA7 15-45套机 目前这两款相机都处于历史最低价附近,XA5套机2699元,XA7套机3999元。XA5就是一个标准的入门级相机,定位就是时尚小巧自拍,在2699这个价位不要对它的性能有太多的奢求。 XA7价格来到了3999元,这就很有意思了,富士把入门型的相机价格推到了4000元,并且提供了自拍翻转屏和4K30P视频录制,这样一款相机就很有性价比了。 XE3是老款的中端相机,价格和入门级的XA7是一样的,都是3999元,这两款相机如何做选择呢?XE3有着更多的按键意味着更好的操控,但屏幕不是自拍翻转屏所以这点不如XA7好用。 要注意的是XE3用的是富士独有的X-Trans™CMOS III传感器,XA7是普通的2400万像素传感器,你可以理解为X-Trans才是富士的精髓。 富士(FUJIFILM)X-E3 15-45套机 当然,买新不买旧,XA7的新功能和自拍翻转屏可能会更适合你。 XT200是富士专门针对vlog市场推出的相机,其实之前的XA7也可以拍摄vlog,但XT200是富士官方宣传中的第一款vlog相机。数码防抖+3.5mm 麦克风口+自拍翻转屏+无裁切4K30P,这些都是XT200的优势,但这款相机也是普通的2400万像素传感器,没有用富士独有的X-Trans,可能是从价格角度考虑做了阉割吧。 富士(FUJIFILM)X-T200/XT200 微单相机 Vlog相机 富士XT30是我认为富士性价比最高的微单照相机,注意我说的是照相机。理由很简单,因为从拍照角度来看XT30和XTXT3几乎没有明显差距,主要是操控差了一些、视频性能大幅削弱,但好歹也是个有着双波轮+曝光补偿波轮+快门速度波轮的相机,操控方面不会太差的。视频方面也有着超采4K 30P的规格,支持F-log输出。 可以这么说,如果你只拍照,那么XT30是富士微单中性价比最高的,视频方面XT30也不差,只不过没有专业的10bit和4K60P而已。 富士(FUJIFILM)X-T30/XT30 15-45套机 XT3和XT4得放在一起说,这两款相机其实都挺好,420 10bit 4K60P的专业视频模式基本代表了APS-C画幅的上限水平。XT4还提升了电池续航增加了五轴防抖,配上富士独特的胶片滤镜,不管是拍照还是拍视频都非常优秀。 不要觉得这两款相机贵,同价位里能做到4K60P的微单也就是M43画幅的GGHGH5S,最便宜的G9机身也要7000多,这APS-C画幅的XT3机身接近8000也算合理价格范围内。除此之外的4K60P机身只有13998的松下S5和15999的佳能R6了。 富士(FUJIFILM)X-T3/XT3 1855套机 富士(FUJIFILM)X-T4/XT4 微单相机 套机(18-55mm) B站更新4K视频投稿后有很多人想拍摄4K升格,在很长一段时间里富士XT3和XT4是最优选,毕竟兼顾视频和拍照,对焦也还算能用。 X-Pro3和X-Pro2这两款微单可以算是旁轴相机,是富士官方意义上的旗舰级相机。从用料做工操控按键角度来说的确是旗舰级别,但视频性能方面只有4K30P,价格却比XT3还贵,可能这就是旁轴情怀带来的溢价吧。 富士(FUJIFILM)X-Pro3 微单相机 机身 黑色 我在之前的文章里提过很多次,有一些相机属于如果你想买你压根不会看测评,如果你犹豫那么这款相机不适合你,为什么这么说,因为有一些比较小众的相机可能在性能上并不好,但独特的外形、操控、体积、传承赋予了它独特的定位。譬如富士X-Pro系列微单就是旁轴的电子化,理光GR传承大师的扫街理念,尼康DF的外形源自胶片时代的相机,这些相机就不是针对大多数消费者的,定位就是小众。所以我说喜欢就买,不要考虑什么性能规格。 X100系列相机是一款不可换镜头的等效35mm旁轴数码相机,从外形看就是经典的复古造型。这两款相机和X-Pro3一样,如果你喜欢那就买,别犹豫, 你在市场上找不到同类型的其他数码相机,徕卡Q是28mm,索尼RX1R系列是35mm但外形不够复古,X100系列就是独特的你没有其他选择。 那么X100F和X100V该如何选择呢?X100F的镜头很一般甚至算不上好,如果我没记错的话和初代的X100是同款镜头,X100V的镜头是全新制作的很棒,X100V的机身性能也和XTX-Pro3差不多。 富士(FUJIFILM)X100F 数码相机 旁轴 2430万像素 富士(FUJIFILM)X100V 数码相机 旁轴 2610万像素 还是那句话,这两款相机也是那种如果你喜欢那就毫不犹豫下单的类型,而且这两款相机也没有竞品。 以前不推荐富士的原因是原厂镜头太贵,现在唯卓仕给富士出了四款可以自动对焦的大光圈镜头,覆盖35到130mm的焦段,可以基本满足人像摄影爱好者的需求。拍风景的话国产很多镜头厂商都有富士卡口的手动镜头可以选择,从这个角度来说富士微单就非常值得入手了。 和友商竞品相比:
-
反传销网8月30日发布:视频区块链里的骗子,币里的韭菜,杜子建骂人了!金融大V周召说区块链!——“一小帮骗子玩一大帮小白,被割韭菜,小白还轮流被割,割的就是你!” 什么区块链,统统是骗子 作者:周召(知乎金融领域大V,毕业于上海财经大学,目前任职上海某股权投资基金合伙人) 有人问我,区块链现在这么火,到底是不是骗局? 我的回答是: 是骗局。而且我并不是说数字货币是骗局,而是说所有搞区块链的都是骗局。 -01- 区块链是一种鸡肋技术 人类社会任何技术的发明应用,本质都是为了提高社会的生产效率。而所谓区块链技术本质不过是几种早已成熟的技术的大杂烩,冗余且十分低效,除了提高了洗钱和诈骗的效率以外,对人类社会的进步毫无贡献。 真正意义上的区块链得包含三个要素:分布式系统(包括记账和存储),无法篡改的数据结构,以及共识算法,三者互为基础和因果,就像三体世界一样。看上去挺让人不明觉厉的,而经过几年的瞎折腾,稍微懂点区块链的碰了几次壁后都已经渐渐明白区块链其实并没有什么卵用,区块链技术已经名存实亡,沦为了营销工具和传销组织的画皮。 因为符合上述定义的、以比特币为代表的原教旨区块链技术,是反效率的,从经济学角度来说,不但不是一种帕累托改进,甚至还可以说是一种帕累托倒退。 原教旨区块链技术的效率十分低下,因为要遍历所有节点,只能做非常轻量级的数据应用,一旦涉及到大量的数据传输与更新,区块链就瞎了。 一方面整条链交易速度会极慢,另一方面数据库容量极速膨胀,考虑到人手一份的存储机制,区块链其实是对存储资源和能源的一种极大的浪费。 这里还没有加上为了取得所谓的共识和挖矿消耗的巨大的能源,如果说区块链技术是屎,那么这波区块链投机浪潮可谓人类历史上最大规模的搅屎运动。 区块链也验证不了任何东西。 所谓的智能合约,即不智能,也非合约。我看有人还说,如果有了智能合约,就可以跟老板签一份放区块链上,如果明年销售业绩提升30%,就加薪10%,由于区块链不能篡改,不能抵赖,所以老板必须得执行,说得有板有眼,不懂行的愣一看,好像还真是那么回事。 但仔细一想,问题就来了。首先,在区块链上如何证明你真的达到了30%业绩提升?即便真的达到老板耍赖如何执行? 也就是说,如果区块链真这么厉害,要法院和仲裁干什么。 人类社会真正的符合成本效益原则的是代理制度。之前有人说要用区块链改造注册会计师行业,我不知道他准备怎么设计,我猜想他思路大概是这样的,首先肯定搞去中心化,让所有会计师到链上来,然后一个新人要成为注册会计师就要所有会计师同意并记录在链上。 那我就请问了,我每天上班累死累活,为什么还要花时间去验证一个跟我无关的的人的专业能力?最优做法当然是组织一个委员会,让专门的人来负责,这不就是现在注册会师协会干的事儿吗?区块链的逻辑相当于什么事情都要拿出来公投,这个绝对是扯淡的。 当然这么说都有点抬举区块链了,区块链技术本身根本没有判断是非能力,如果这么高级的人工智能,靠一个无脑分布式记账就能实现的话,我们早就进入共产主义社会了。 虽然EOS等数字货币采用了超级节点,通过再中心化的方式提高效率,有点行业协会的意思,是对区块链原教旨主义的一种修正,但是依然无法突破区块链技术最本质的局限性。有人说,私有链和联盟链是区块链技术的未来,也是扯淡,因为区块链技术没有未来。如果有,说明他是包装成区块链的伪区块链技术。 区块链所涉及的所有底层技术,不管是分布式数据库技术,加密技术,还是点对点传输技术等,基本都是早已存在没什么秘密可言的技术。 比特币系统最重要的特性是封闭性和自洽性,他验证不了任何系统自身以外产生的信息的真实性。 所谓系统自身产生的信息,就是数据库数据的变动信息,有价值的基本上有且只有交易信息。所以说比特币最初不过是中本聪一种炫技的产物,来证明自己对几种技术的掌握,你看我多牛逼,设计出了一个像三体一样的系统。因此,数字货币很有可能是区块链从始至终唯一的杀手应用。 比特币和区块链概念从诞生到今天已经快10年了,很多人说区块链技术在爆发的前夜,但这个前夜好像是不是有点过长了啊朋友,跟三体里的长夜有一拼啊。都说区块链技术像是90年代初的互联网,可是90年代初的互联网在十年发展后,已经出现了一大批伟大的公司,阿里巴巴在99年都成立了,区块链怎么除了币还是币呢? 正规的数字货币未来发展的形式无外乎几种,要么就是论坛币形式,或者类似股票的权益凭证等。问题是论坛币和股票之前,本来也都电子化了,区块链来了到底改变了什么呢? 所有想把TOKEN和应用场景结合起来的人最后都很痛苦,最后他们会发现区块链技术就是脱裤子放屁,自己辛苦搞半天,干嘛不自己作为中心关心门来收钱?最后这些人都产生了价值的虚无感,最终精神崩溃,只能发币疯狂收割韭菜,一边嘴里还说着我是个好人之类的奇怪的话。 因此,之前币圈链圈还泾渭分明,互相瞧不起,但这两年链圈逐渐坐不住了,想着是不是趁着泡沫没彻底破灭之前赶快收割一波,不然可能什么都捞不着了。 前段时间和一个名校毕业的链圈朋友瞎聊天,他说他们“致力于用区块链技术解决数字版权保护问题”,我就问他一个问题,你们如何保证你链的版权所有权声明是真实的,万一盗版者抢先一步把数据放在链上怎么办。他说他们的解决方案是连入国家数字版权保护中心的数据库进行验证…… 所以说区块链技术就是个鸡肋,研究到最后都会落入效率与真实性的黑洞,很多人一头扎进链圈后才发现,真正意义上的区块链技术,其实什么都干不了。 -02- 不是蠢就是坏的区块链媒体 空气币和区块链的造富神话,让区块链自媒体也开始迎风乱扭。一群群根本不知道区块链为何物的妖魔鬼怪纷纷进驻区块链自媒体战场,开始大放厥词胡编乱造。 任何东西,但凡只要和区块,链,分,分布式,记账,加密,验证,可追溯等等这些个关键词沾到哪怕一点点,这些所谓的区块链媒体人就会像狗闻到了屎了一样疯狂地把区块链概念往上套。 这让我想起曾经一度也是热闹非凡的物联网,我曾经去看过江苏一家号称要改变世界的“物联网”企业,过去一看是生产路由器的,我黑人问号脸,对方解释说没有路由器万物怎么互联,我觉得他说得好有道理,竟无言以对。 好,下面让我们进入奇葩共赏析时间,来看看区城链媒体经常有哪些危言耸听的奇谈怪论 区块链(分布式记账)的典型应用是*?? 正如前面所说,真正意义上的区块链分布式记账,不光包括“记”这个动作,还包括分布式存储和共识机制等。而*诞生远远早于区块链这个词的出现,勉强算是“分布式编辑”吧,就被很多区块链媒体拿来强行充当区块链技术应用的典范。 其实事实恰恰相反,*恰恰是去中心化失败的典范,现在如果没有精英和专业人士的编辑和维护,*早就没法看了。 区块链会促进社会分工?? 罗振宇好像就说过类似的话,虽然罗振宇说过很多没有逻辑的话,但这句话绝对是最没逻辑思维的。很多区块链自媒体也常常用这句话来忽悠老百姓,说分工代表效率提高社会进步,而区块链“无疑”会促进分工,他们的理由仅仅是分工和分布式记账都共用一个“分”字,就强行把他们扯到一起。 实际情况恰恰相反,区块链是逆分工的,区块链精神是号召所有人积极地参与到他不擅长也不想掺合的事情里面去。 区块链不能像上帝一样许诺他的子民死后上天国,只能给他们许诺你们是六度人脉中的第一级,我可以赚后面五级人的钱,你处于金字塔的顶端。
-
RocketMQ 为什么这么快?我从源代码中找出了十大原因!