架构视角-文件的通用存储原理

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
简介: 架构师是互联网行业高薪又紧俏的资源。成为架构师最基本的是设计能力。设计与设计的区别主要体现在两方面:1,深度:要解决哪些问题?这个问题背后的根本问题是什么?还有什么问题没有发现?对应的能力是发现和解决问题的能力。2,体系:要解决的问题的属于哪一类的问题?这类问题能否进一步抽象,让系统解决更大的问题?对应的抽象归纳和体系化思维的能力。

架构师是互联网行业高薪又紧俏的资源。成为架构师最基本的是设计能力。设计与设计的区别主要体现在两方面:


1,深度:要解决哪些问题?这个问题背后的根本问题是什么?还有什么问题没有发现?对应的能力是发现和解决问题的能力。


2,体系:要解决的问题的属于哪一类的问题?这类问题能否进一步抽象,让系统解决更大的问题?对应的抽象归纳和体系化思维的能力。


而做架构的基本功就是研究成熟成功的系统,并总结归纳为一种设计方法添加到自己的设计库中。今天我们来看看文件存储机制的通用实现及原理-谈Kafka、Redis、基于Lucene的搜索引擎等中间件和数据库的文件存储机制。如果你有九年义务教育以上学历,并且觉得看不懂这篇文章,请给我留言~~


顺便插一句,不知道大家有没有奇怪静儿最近都没有写高可用方面的文章。事情是这样的,对于高可用的很多设计、架构,静儿都在进行专利申请中,为了避免对公司造成影响和损失,暂时处于多想不说的阶段。


   一个商业化中间件的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一。下面先介绍一下各个中间件的存储机制。看不懂可直接跳到最后。

各个中间件的存储机制

 

1Kafka  

 

Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协议的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。


设计特点


Kafka把topic中一个partition(大块)大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完的文件,减少磁盘占用。


通过索引信息可以快速定位message和确定response的最大大小。


通过index(索引)元数据全部映射到memory(内存),可以避免segment file(文件片段)的IO磁盘操作。


通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。


   一张图解释一下刚才说的特点:


12132328-d56e827212dfa735.jpg


  从上面的图中可以看到,生产者和消费者并没有直接的交互。这就达到了生产者消费者模式的第一个好处:解耦。作为消费者,可以自定义消费线程数和消费者数量。这就达到了生产者消费者模式的第二个好处:限流。这也是大家使用MQ一般想要达到的目的。


2Redis  

 

   谈redis首先要纠正一个误区:缓存比mysql快。为了说明这个问题,下面是静儿自己动手得到的数据。


结论:使用了缓存后响应时间不稳定

image.gif

网络异常取消重新上传


结论:mysql的响应时间非常稳定

image.gif

网络异常取消重新上传


从cat监控中可以看到缓存的get时间确实较长。


12132328-8374deb910221d58.jpg


顺便跑题一下,静儿测试中还发现在jvm正常执行业务逻辑,不太复杂无外部调用,一般是1到2毫秒。但是如果抛出了异常,这段代码执行时间要变成100ms+。所以一般代码中禁止用抛出非必要异常来代替正常逻辑。


12132328-9f7fc5ef0be58176.jpg


之所以给大家打这个预防针,是因为下面要给出Redis的描述了。


Redis本质上是一个key-value类型的内存数据库,整个数据库加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是已经性能最快的key-value DB。


Redis存储机制分成两种Snapshot和AOF。无论是哪种机制,Redis都是将数据存储在内存中。


AOF工作原理:是将数据先存在内存,但是在存储的时候会使用fsync(无阻塞进程的)来完成对本次写操作的日志记录。AOF最关键的配置就是关于调用fsync追加日志文件的频率,有两种预设频率。always:每次记录进来都添加。everysecond每秒添加一次。


存储模式性能和安全比较:


1.性能


snapshot性能是要明显高于AOP方式的,原因有两点:


1>采用二进制方式存储,数据文件小,加载快速。


2>存储的时候是按照配置中的save策略来存储,每次都是聚合很多数据批量存储,写入的效率高。AOF一般都是工作在实时或准实时模式下。相对存储频率高,效率低。


2.数据安全


AOF数据安全性高于Snapshot,原因:


snapshot存储是基于累积批量的思想,累积的数据越多写入效率越高,但是如果长时间数据不写入RDB(redis的数据库),redis遇到了崩溃,没写入的数据就无法恢复。


   Redis中有rewrite功能,AOF的存储是按照记录日志的方式去工作的,成千上万的数据插入必然导致日志文件的扩大,Redis这个时候会根据配置合理触发rewrite操作。这个操作是将最终保留值记录到日志文件中,从而缩小日志文件的大小。这个类似于lucene的optimize操作。

 

3Mysql/MariaDB  

 

Mysql与目前流行的nosql数据库最大的不同是规定了严格的数据类型。数据类型因为在创建表时在内存中严格划定了地址空间,所以能限定字段的数据存储长度。


   数据类型限定范围的方式有两种:1是严格限定空间,划分了多少空间就只能存储多少数据,超出的数据将被切断;2是使用额外的字节的bit位来标记某个数据,存储了就进行标记,不存储就不标记。下面介绍3种类型的存储方式。


1.整形的存储


它严格限定空间,每个已划分的字节上的bit位上的0和1直接可以计算出数值,所以它的范围是根据bit位的数量值来计算的。一个字节有8个bit位,一个bit位可以构成2的8次方=256个数值。同理2字节共2的16次方=65526个数值。也就是说,在0-255之间的数字都只占用1个字节,256-65535之间的数字占用2个字节。


2.char的存储


char类型是常被成为定长字符串类型,它严格限定空间长度,但它限定的是字符数不是字节数。它有“短了就使用空格补足”的能力。


3.varchar常被称为“变长字符串类型”。它存储数据时使用额外的字节的bit位来标记某个字节是否存储了数据。每存储1个字节占用一个bit位进行标记。一个额外的字节可以标记256个字节,2个额外的字节可以标记65536个字节。MySQL/mariadb限制了最大能存储65536个字节。这表示,如果是单字节的字符,它最多能存储65536个字符,如果是多字节字符,如UTF8的每个字节占用3个字节,它最多能存储65536/3=21845个字符。

 

4基于Lucene的搜索引擎  

 

提到基于Lucene的搜索引擎,大家可能更熟悉ElasticSearch(ES)。静儿有段时间专门负责公司的搜索,没有现在这么忙,本应该是非常难得和宝贵的机会。有大把的时间研究源码,可惜当时整个心都不在工作上。当时用的还是solr4.X.X(solr是基于Lucene的搜索引擎系统,lucene和solr版本同步更新,目前最新是7.6.0),当时solr每月发布一个新版本。版本有很多bug,我当时是在源码上做了很多修复补丁的。但是当时各种意识都很薄弱。如果当初给apache提patch,有些应该是能通过的。这就能形成了一个良好的反馈循环,可能现在的状况截然不同。


   想起dubbo有段时间已经不更新版本,后来捐给了apache,给这个项目又重新注入了生机。其中的一个教训就是大家一定要有很强的开源意识。这种意识还包括在自己做功能方案和开发实现的时候要有业界调研和对标的意识。


静儿的梦想是实现自己的搜索引擎中间件,所以目前从事的是和这个原理有很深渊源的工作:容器调度。什么?看不出来联系?那这个以后再慢慢聊。


Lucene的数据都存在一个目录下,一个目录构成了一个索引。Lucene经多年演进优化,现在的一个索引文件可以分为4个部分:词典、倒排表、正向文件、列式存储。一张表解释lucene的存储原理:


12132328-885792a2632a3dcd.jpg


通用原理


   1.高频读取操作放于内存。


2.文件分段减少磁盘IO操作。


3.磁盘存储防止数据丢失。


4.更好的结构化可以提升存储和读取效率。


以上です。不解释。


总结


     之前和同事聊天,同事说他们架构师基于原来的版本设计了一个非常完美的2.0方案。但是这个方案并不解决现有的任何问题。这也是静儿想做架构并且可以很轻松的找到一个架构师职位,但一直都是在项目组内自己动手写代码的原因:一个旁观者想了解内部的痛点很困难。


前段时间大家纷纷剖析拼多多优惠券事件背后的技术问题。不可否认,技术是有点菜。但是拼多多目前整体看是成功的。成功在哪里呢?它成功的解决了商家(其他平台门槛高,入住不了)和消费者(以更低的价格买到商品)的痛点。所以这点状况并未伤及元气。


   在做设计的时候,我会首先问自己一个问题:现在哪里最痛?架构讲究深度和体系。深度解决的是痛点根本性的问题。体系解决的是未来的痛点问题。不以解决问题为目的设计的系统都是“成功之母”。

相关文章
|
2月前
|
分布式计算 大数据 数据处理
经典大数据处理框架与通用架构对比
【6月更文挑战第15天】本文介绍Apache Beam是谷歌开源的统一数据处理框架,提供可移植API,支持批处理和流处理。与其他架构相比,Lambda和Kappa分别专注于实时和流处理,而Beam在两者之间提供平衡,具备高实时性和数据一致性,但复杂性较高。选择架构应基于业务需求和场景。
96 3
经典大数据处理框架与通用架构对比
|
2月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
23天前
|
NoSQL Redis
Redis 主从复制架构配置及原理
Redis 主从复制架构配置及原理
32 5
|
26天前
|
机器学习/深度学习 SQL 自然语言处理
现代深度学习框架构建问题之深度学习通用架构的定义如何解决
现代深度学习框架构建问题之深度学习通用架构的定义如何解决
30 3
|
4天前
|
存储 缓存 Java
Eureka原理与实践:深入探索微服务架构的核心组件
在微服务架构日益盛行的今天,服务之间的注册与发现成为了保证系统高可用性和灵活性的关键。Eureka,作为Netflix开源的服务注册与发现框架,凭借其简单、健壮的特性,在微服务领域占据了举足轻重的地位。本文将深入剖析Eureka的原理,并通过实践案例展示其在实际项目中的应用,以期为开发者提供一个高端、深入的视角。
11 0
|
5天前
|
消息中间件 缓存 Kafka
图解Kafka:架构设计、消息可靠、数据持久、高性能背后的底层原理
【8月更文挑战第15天】在构建高吞吐量和高可靠性的消息系统时,Apache Kafka 成为了众多开发者和企业的首选。其独特的架构设计、消息可靠传输机制、数据持久化策略以及高性能实现方式,使得 Kafka 能够在分布式系统中大放异彩。本文将通过图解的方式,深入解析 Kafka 的这些核心特性,帮助读者更好地理解和应用这一强大的消息中间件。
20 0
|
1月前
|
Dart JavaScript Java
flutter 架构、渲染原理、家族
flutter 架构、渲染原理、家族
40 2
|
1月前
|
存储 关系型数据库 分布式数据库
PolarDB,阿里云的云原生分布式数据库,以其存储计算分离架构为核心,解决传统数据库的扩展性问题
【7月更文挑战第3天】PolarDB,阿里云的云原生分布式数据库,以其存储计算分离架构为核心,解决传统数据库的扩展性问题。此架构让存储层专注数据可靠性,计算层专注处理SQL,提升性能并降低运维复杂度。通过RDMA加速通信,多副本确保高可用性。资源可独立扩展,便于成本控制。动态添加计算节点以应对流量高峰,展示了其灵活性。PolarDB的开源促进了数据库技术的持续创新和发展。
249 2
|
1月前
|
监控 Kubernetes 持续交付
后端开发中的微服务架构:原理、优势与实践
本文深入探讨了在现代后端开发中,微服务架构如何成为提升系统可维护性、扩展性和敏捷性的关键技术。文章首先定义了微服务并解释了其核心原理,随后通过数据和案例分析,展示了微服务架构如何优化开发流程和提高系统性能。最后,文中提供了实施微服务架构的实用建议,旨在帮助开发者更好地理解和应用这一架构模式。
|
29天前
|
SQL
云架构数据倾斜问题之在SQL数据源读取查询时合并小文件如何解决
云架构数据倾斜问题之在SQL数据源读取查询时合并小文件如何解决