当前位置: 首页 > 科技观察

吐血总结了各个中间件是如何实现持久化的

时间:2023-03-16 19:57:32 科技观察

吐血总结了各个中间件是如何实现持久化的。转载本文请联系Java3y公众号。到目前为止,三外也接触了很多中间件,比如“Elasticsearch”、“Redis”、“HDFS”、“Kafka”、“HBase”等等。可以发现它们的持久化机制并没有太大区别。今天想总结一下。一方面,我想审查这些组件。另一方面,我想为还没有入手这些中间件的同学总结一下执着的“套路”。以后学起来会容易很多。这些中间件都在我的GitHub目录下:https://github.com/ZhongFuCheng3y/3yhttps://gitee.com/zhongfucheng/Java3y持久化我们分别回顾一下每个中间件/组件持久化机制可以总结在最后(三外相信大家应该能从复习中看出一些端倪)为什么是坚持?原因也很简单:数据需要存储,不想因为问题导致数据丢失。ElasticsearchElasticsearch是一个非常擅长模糊搜索的全文搜索引擎。Elasticsearch写入数据时,先写入内存缓冲区,再写入translog缓冲区,每隔5s将translog缓冲区中的数据刷新到磁盘。卡夫卡是众所周知的。Kafka是一个高吞吐量的消息队列,那么它是如何持久化的呢?Kafka严重依赖文件系统来存储和缓存消息。是的,Kafka使用文件系统进行存储。其实Kafka官网上也说,Kafka的持久化是靠操作系统的pagecache和顺序写入来实现的。HDFSHDFS是一个分布式文件系统,可以存储海量数据。写数据的时候HDFS呢?HDFSClient不管是读还是写,都需要去NameNode获取/增加/删除/修改文件元数据。NameNode是维护这些元数据的地方。所以,要在HDFS中写入数据,需要先到NameNode中去询问这些分块要写入到哪些DataNode中。为了提高NameNode的效率,在写入数据的时候,NameNode实际上是对内存进行操作,然后将增删改相关的数据依次写入到editlog日志文件中。RedisRedis是基于内存的。如果不想把数据保存在硬盘上,一旦Redis重启(退出/故障),内存中的数据就会全部丢失。我们肯定不希望Redis中的所有数据因为某些故障而丢失(导致所有请求都转到MySQL)。即使发生故障,我们也希望Redis中的数据能够恢复到原来的状态,所以Redis有RDB和AOF持久化机制。RDB:基于快照,将某一时刻的所有数据保存在一个RDB文件中。AOF(append-only-file),当Redis服务器执行写命令时,将执行的写命令保存到AOF文件中。AOF持久化功能的实现可以分为3步:命令追加:命令写入aof_buf缓冲区文件写入:调用flushAppendOnlyFile函数,考虑是否将aof_buf缓冲区写入AOF文件文件同步:考虑是否缓冲内存区中的数据实际上写入硬盘的HBaseHBase是一个可以存储海量数据的数据库。HBase写入数据时,会先写入MemStore。当MemStore超过一定阈值时,会将内存中的数据写入硬盘,形成StoreFile,StoreFile底层以HFile格式保存。KeyValue数据的存储格式。我们写数据的时候,先写入内存。为了防止宕机,内存中的数据在刷到磁盘之前先挂了。我们在写Memstore的时候,也会写一份HLogMySQLMySQL。我们用的最多的InnoDB引擎是怎么存储的呢?具有redolog支持持久化功能。MySQL引入了重做日志。内存写入后,会写入redolog。这个redolog记录的是这次对某个页面进行了哪些修改。看完以上常见的中间件/组件的持久化方式,就不用我多说了。想法几乎相同,只是他们的“日志”名称不同。先写buffer,再顺序IO写log。防止buffer中的数据被flush到磁盘,导致宕机导致数据丢失。对于Log文件,中间件不会让其不断扩容,导致体积变大:在Redis中,AOF文件会被改写在HDFS中,editlog会定时生成fsimage在Elasticsearch中,translog会根据阈值触发commit操作。....