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

NoSQL的江湖称霸之路示意图

时间:2023-03-18 17:08:53 科技观察

1.糊涂小黑小黑最近有点郁闷。不太喜欢手头的工作,技术倒退有点严重,想出去看看机会。小黑是朋友推荐的。前些天,他去一家叫宇杰崩局的公司面试,被一些问题给撞倒了。大白安抚小黑说道:“黑哥,你要知道,没有好工作,只有好工人。其实哪里都一样,都是兼职!”是架构师!”小黑骂了大白一句,毕竟他不想当架构师是因为他后端程序员不好,然后就开始说他遇到的问题。面试官问他喜欢哪个领域,小黑说是分布式存储,面试官附和:“确实是个好领域,那我问你几个存储相关的问题吧!”小黑心里暗自觉得这个问题在知识面广,所以面试官问了几个问题:a.你在实际工作中用过什么NoSQL?b.SQL和MySQL相比有什么优缺点?c.你了解WAL和LSM的底层机制吗?d.设计一个NoSQL应该考虑什么?听完这些问题,小黑慌了很多,几句话后面试官也看到了小黑关于存储的知识边界,出于友好礼貌地不再问了。礼仪,我问了小晓几件事小黑的简历,终于结束了面试。大白听了也有些慌了。毕竟,他自己也不会,故作镇定的说道:“黑哥,你这几个问题很典型。我会在周末写一篇文章,告诉你这件事。”小黑笑道:“哈哈哈,我就等着你呢。上周刚吃过烧烤,这周刚吃过火锅。”大白和小黑真是吃喝二人组。言归正传,让我们开始NoSQL之旅吧!它最早出现于1998年,受限于当时的技术场景和应用,没有掀起太大的波澜。不过NoSQL在2009年又被提出来了,这次出场有点炸裂,明日之星也不少。一般来说,这东西行不通,跟slogan有很大关系。我理解的口号是:人生不易,早退早。在2009年亚特兰大的一次重要会议上,为NoSQL提出了一个优雅且响亮且略带挑衅性的口号:selectfun,profitfromreal_worldwhererelational=false;NoSQL本质上是对一类数据库的统称,分为以下几种:只介绍键值对key-value数据库,先看NoSQL名称来源和含义的几种解读:释义NoSQL的意思是“NoSQL”,译为SQL已死。潜台词就是这类数据库没有SQL语句,放弃老大哥MySQL的方式,让它退休。嘿,好家伙,口气不小。事实证明,这种“SQL已死”的自信确实有点扯。解读2NoSQL的意思是“NotOnlySQL”,显然没有那么嚣张,它增加了一点谦虚,notonlySQL,除了继承老大哥MySQL的一些功能外,还加入了新的东西,听起来不错。解读3NoSQL本质上是一种非关系型数据库。我们都知道关系型数据库一般简称为RDS或RDB,所以有人认为NoSQL应该叫“NoRelationalDatabase”,简称“NoRelationshipDatabase”。综上所述,比起“NotOnlySQL”这种作为关系型数据库的补充而存在的新型数据库,我们更喜欢NoSQL。3.给NoSQL一首时间之歌。工欲善其事,必先利其器。大家都这么忙,一定要给学习NoSQL的理由。我们试着想象几个熟悉的场景:场景一:大雄组长给小黑一个请求,需要在MySQL中增加一个上千万行的字段。由于是生产环境,需要找DBA手动执行。对小黑来说,来不及了,也不方便。场景二大雄组长又给了小黑一个存储数据包的请求。数据包其实是一个Json字符串,里面有很多字段,但是不清楚怎么用PM,字段会不会调整,所以用MySQL存储,字段还是不确定的,所以小黑补充道一个额外的字段,用于存储后续扩展,暂时解决。场景3大雄组长让小黑设计一个并发量更大的服务来完成用户账号系统查询。目前有近4亿个帐户ID。大雄开发了C++服务,存储选择了MySQL。性能根本无法提高。真是不知所措。MySQL在世界上横行了几十年,无人能敌,尤其是在事务、数据一致性、关联查询等场景。它具有绝对的优势。技术的进步,新的和常用的新形式的出现,也让MySQL有些捉襟见肘。毕竟MySQL也不是万能的。要保持自己的地位,就必须与时俱进。在很多场景下,我们并不需要事务、数据强一致性、多表关联等特性,所以我们需要一个更轻量级的数据库,这就是NoSQL。4.MySQLvsNoSQL我们需要比较一下MySQL和NoSQL来加深印象:MySQL是高度组织化和结构化的数据存储,NoSQL是非结构化存储MySQL使用结构化查询语句,NoSQL没有查询语言MySQL需要定义字段和模式,NoSQL自如扩展MySQL,读写性能不如NoSQL,MySQL在扩展海量数据时扩展性差高并发、高可用性、高扩展性的新需求对NoSQL提出了要求。NoSQL之所以能够应对这些新场景,与其设计思路有很大关系。或许可以用葡萄来解释为什么NoSQL更适合高并发场景。NoSQL是一串葡萄,访问非常方便,读写速度也很快这么多,一起来看看大白在实际工作中用过的一些NoSQL吧!5、NoSQL开源的NoSQL明星项目非常多。大白根据层级选出几个典型代表分享给大家。NoSQL可以是单机的,也可以是分布式的,可以根据自己的用途来使用。今天要介绍的几个数据库:Redis、Pika、SSDB、RocksDB、LevelDB。其中LevelDB是Google开发的,RocksDB是Facebook开发的,在LevelDB的基础上增加了新的特性,Redis就不用说了,SSDB和Pika都是国内开源的类Redis数据库,也很不错。下面我们就来看看这些数据库的特点、联系、底层原理等有趣的东西。5.1Google出品的LevelDBLevelDB是由Google的SanjayGhemawat和JeffDean使用C++开发的单进程/单机持久键值数据库。2011年7月开源,可以说是一鸣惊人的产品。LevelDB支持最基本的key-value操作:Get/Put/Delete,但是并没有封装其他的东西。严格来说,它只是一个NoSQL存储引擎。一般来说,机械盘最怕的就是随机读写。如果磁盘在旋转,则意味着读写效率正在下降。LevelDB具有很高的随机写和顺序读/写性能,所以LevelDB非常适合写多读少的场景。真是让人想知道高性能的随机写是怎么实现的。5.1.1LSM树中的很多数据在逻辑上是相似的,但在物理存储上可能相距很远,这会造成大量的随机读写问题,从而降低性能。LevelDB实现高性能随机写的秘密武器是使用LSM树存储结构。LSM树也称为日志结构合并树(Log-StructuredMerge-Tree)。它不是具体的数据结构,而是一种设计思想。对于每一次写操作,LSMtree并不直接将最新的数据存入磁盘,而是先将数据放入内存中。当内存数据达到一定的阈值时,这部分数据实际上会刷新到磁盘文件中,从而将磁盘随机写入转换为内存顺序写入,从而获得极高的写入性能,但这种机制会降低读取性能。一般来说,为了大幅度提高写性能,降低部分读性能是值得的。5.1.2LevelDB的总体架构LevelDB的存储结构主要由六部分组成:MemTable:内存数据结构,使用SkipList实现,新的数据修改会先写到这里,有容量限制。ImmutableMemTable:数据库要放在磁盘上的内存结构。当MemTable的大小达到设定的阈值时,就会变成ImmutableMemTable,只接受读操作,不再接受写操作。稍后将其刷新到磁盘。SSTFiles:SortedStringTableFiles,磁盘数据存储文件,分为Level0到LevelN多层,每一层包含多个SST文件,文件中的数据是有序的。ManifestFiles:leveldb元信息清单文件。Manifest记录了SST文件在不同层级的分布情况,相当于SST文件的索引。当前文件:当前正在使用的文件列表文件。LevelDB的读写过程与上述整体架构密切相关。首先是内存,其次是磁盘,逐层读取查找数据。5.2Facebook出品的RocksDB比blue好。RocksDB在LevelDB的基础上进行了改进和优化,也成为了后来很多NoSQL选择的存储引擎。RocksDB依然是用C++开发的,完全向下兼容了LevelDB的接口,可以说是平滑升级。5.2.1RocksDB改进点来看看RocksDB做了哪些优化和改进:RocksDB支持一次获取多个key,也支持key范围搜索,而LevelDB只能获取单个key。RocksDB支持多线程合并,而LevelDB是单线程合并,前者在多核时代效率更高。RocksDB添加了一个合并过滤器来丢弃不合格的键。RocksDB可以使用多种压缩算法,除了LevelDB使用的snappy,还有zlib和bzip2。RocksDB支持增量备份和全量备份。RocksDB支持流水线Memtable,使用多个Memtable,而LevelDB只有一个Memtable。5.2.2RocksDB整体架构Rocksdb引入了ColumnFamily的概念。所谓列族就是由一系列kv组成的数据集。所有的读写操作都需要先指定列族。每个ColumnFamily都有自己的Memtable和SST文件,所有ColumnFamily共享WAL、Current和Manifest文件。如果说LevelDB是NoSQL存储引擎的民用版,那么RocksDB绝对是尊贵版,所以很多优秀的NoSQL产品都是基于RocksDB来封装上层协议和代理支持。5.3ideawu的SSDBSSDB是一个基于SSD作为底层存储介质的类Redis数据库。Redis太迷人好用了,但是太贵了,于是我们就幻想有一个支持Redis数据结构,容量无限的数据库。这种数据库结合了Redis数据结构的优点和廉价的磁盘介质,真是令人着迷。没错,SSDB就是这样一个NoSQL数据库。目前SSDB的维护者还不多,在集群等方面还存在一些问题,但也算是一个非常不错的开源NoSQL。先简单了解一下SSDB的基本架构:简单来说,SSDB在LevelDB和Redis协议之间进行一层转换,实现命令和数据的切换。这是为了在使用存储引擎形成完整的NoSQL之前封装额外的部分。5.4360出品的Pika其实SSDB和Pika是有密切关系的。SSDB的作者曾在360工作,当时在360的生产环境中广泛使用SSDB。Pika数据库是360基于RocksDB高性能NoSQL开发的集群。Pika是由360DBA团队和基础架构团队使用C++语言共同开发的类Redis存储系统,因此它完全支持Redis协议。Pika是一个持久化的大容量Redis存储服务,解决了Redis存储数据量巨大导致内存不足的容量瓶颈,支持全量同步??和部分同步。Pika还提供了迁移工具,实现Redis数据向Pika的平滑迁移。Pika的定位目标不是取代Redis,而是作为Redis的补充,性能肯定会低于Redis。从整体架构可以看出Pika是通过多线程实现的,所以使用多核效率更高。虽然单线程性能不如Redis,但是多线程一起性能也不错。Pika目前在360内部广泛使用,在其他一些互联网公司也有使用。NoSQL毕竟是个实践项目,这篇文章也不能讲太多,否则就是空洞无意义。5.5其他NoSQL基本上很多互联网公司都会基于LevelDB或者RocksDB开发自己的Key-Vaule数据库,有的只支持简单的字符串结构,有的完全兼容Redis协议和客户端。大部分都是解析Redis协议,使用Redis客户端,增加一层命令解析和数据格式解析,可能还有多线程支持&master-slave&clustering。自己开发一个简单的NoSQL可以大大提高你对NoSQL的理解。github上有很多这样的项目,大家可以参考学习。6、本文小结本文简单讲解NoSQL的一些相关知识点,以及笔者实践过的一些NoSQL。大体原理本质上是相似的,但是要打造一个高性能高可用的工业级NoSQL是非常困难的。