NoSQL 在腾讯应用实践

一、前言
  NoSQL的历史很长,最早可以追朔到Berkeley DB等嵌入式数据库的年代。互联网行业的高速发展对大数据的需求,为NoSQL的发展起到了推波助澜的作用。互联网时代的NoSQL,源起于Google为解决大数据的存储与计算而提出的GFS + Bigtable + Map Reduce。随后Hadoop(Hdfs+Hbase+MapReduce)、 Hypertable、Memcached,Tokyo cabinet,Redis, Dynamo,Cassandra等等NoSQL 产品雨后春笋般的推出,使得Nosql技术广泛应用于互联网各个领域。
  在腾讯过去的几年中,互联网社交平台取得令人瞩目的发展。包括平台用户基数、在线、应用数都取得突飞猛进的增长;另外随着开放的加剧,还有越来越多的第三方选择社交平台开发应用。这些外部条件的变化对技术平台的而言,也带来了新挑战:除需要为用户提供更强的海量服务外,同时还需要提供开放的软件基础架构来帮助第三方开发海量服务。
  在解决这些问题的实践中,总结了很多经验。其中关键一点则是通过NoSQL技术来构建海量服务的数据层,并通过分析和总结出不同的业务场景和技术特点,为各种场景提供更合适的数据层解决方案。具体而言:
 相册、日志等UGC类应用,主要是自我产生数据,他人以浏览为主,其技术特点是读取量巨大,修改量低于读取量一个量级,数据量从几百T至P级不等。提供SAS、SATA级的TDB、TFS解决方案。
 农牧场等Social Game类应用,核心数据是用户背包数据,互动性很强,其技术特点是巨大读取量与修改量,数据量在百G级别。提供MEM级的TMEM解决方案。
 信息中心的Feeds类应用,其技术特点是巨大的修改量与读取量,数据量也在几十T到几百T不等。提供SSD级的TSSD解决方案。


二、【2006~2008】因QQ相册而研发TFS、TDB
  回顾NoSQL在腾讯的发展历程,需要从2006年腾讯分布式文件系统TFS 的研发开始谈起,TFS目的是在公司内部构建统一的存储平台,为各个BU提供文件系统服务。第一期的重点是要能够支持到QQ相册的快速发展。当时QQ相册使用传统企业级存储硬件+标准linux文件系统的老架构,在数百亿的图片数,每天近10亿长尾下载的规模下已难以为继。通过分析,老架构主要有下面三个问题:
 采用FC-SAN等高端企业级存储硬件,这些硬件主要是针对电信、银行等高ARPU值的行业客户而生,价格通常比较贵,对盛行免费的互联网企业来说,成本压力大。
 使用通用的linux文件系统,对相册海量小文件的场景,空间利用和IO性能都不能很好的满足要求。
 元数据与对象数据耦合,扩展性和可维护性较差,单机故障以及扩容都是异常繁琐的运维操作。
  TFS采用廉价的存储设备,在软件层面使用类似软raid的技术来满足系统基于不可靠硬件的可靠性要求。将对象数据与元数据分离:对象数据存储采用自研的CHUNK文件系统,inode节点更小,空间分配采用了基于append + delete更为紧凑的管理方式,使得单机最大可以支持数10亿的图片文件;元数据使用MYSQL存储。系统架构如下:

  上面的架构很好的满足了数百亿级别规模下的QQ相册业务发展。大致在07的时候,QQ相册采用TFS的新架构趋于稳定,同时业务发展需要,对用户上传也放开了限制,用户上传浏览的活跃度上升的一个新的量级,用户目录、文件索引等元数据规模突破千亿。在使用MYSQL应对如此大规模的元数据的场景下,暴露出一些问题:
 索引低效:在QQ相册的场景,上千亿的记录,使用MYSQL的B树索引索引的存储量消耗都在数TB到数十TB。 海量索引在无法全内存的情况会带来IO的多次访问,一方面增加了单次访问的时延,另一方面降低了磁盘的IO利用率。
 数据搬迁:每天数亿的图片上传导致系统扩容,IDC分布策略,导致数据搬迁是常态。使用MYSQL,使用select逐条记录方式搬迁,不同的记录分散在不同的磁盘偏移,一方面搬迁速度较慢,另一方面由迁移导致的磁盘随机IO与业务正常访问相互交织在一起,从而影响到在线业务访问。
 系统控制:MYSQL更多针对是各种数据通用场景所做的设计与开发,实现较复杂。在使用中遇到性能问题,异常故障时难以定位原因,对业务系统来说,已经是无法打破的天花板。
针对上面的问题结合业务需求,07年底研发出TDB用以替代MYSQL,TDB是一个典型的K-V存储系统。其特点是:接口简单,性能高效,具备优秀的扩展能力。

  数据层面,索引设计使用HASH,通过KEY可直接定位磁盘物理偏移,避免B树设计导致的二次定位磁盘性能开销,解决索引低效的问题。同时采用16MB大磁盘块的设计,使得TDB的数据迁移速度可达网卡性能上限,解决迁移性能问题。另外系统可控性更强,一方面因为是专用场景,所以可以简化设计,方便定位问题与优化更新;另一方面打通了存储系统到磁盘IO的控制路径,避免MYSQL的系统天花板。
  接入层面,为业务提供透明的访问代理,从而实现无缝的水平扩展。由于接口简单,并且是PAAS,业务使用非常方便,从07年底开始,在Qzone、朋友、群空间等社区应用中逐步取得了广泛应用。
三、【2009】Social Game催生的TMEM
  09年有一款叫农场的游戏大家应该不会陌生,农场的火爆带动了一批Social Game应用的兴起。其典型特点(1)好友间互动性很强,用户背包数据会被频繁的修改与读取;(2)交叉访问,无明显热点数据;举个例子来说,对于传统的应用来说,用户间交互相对较弱,活跃用户数据就是热点数据;而对于Social Game而言,用户交互性强,通过交叉访问,活跃用户也会频繁访问与修改非活跃用户数据。(3)放大效果明显;比如用户每次登陆,通常会遍历好友的农场,会遍历菜地偷菜,捉虫,一次偷菜、捉虫会导致多个用户的多个背包数据修改。这些行为一方面导致整个系统中无明显热点数据,用户传统的读缓存+写落地的方式则难以很好的满足这些业务的需求;另一方面庞大的用户基数之上的火爆应用,往往单款应用就会有数百万次每秒的访问量,这种海量访问不光对存储层面,同时对网络通讯层面提出更高的性能要求。
  针对以上新兴面临的问题,很明显TDB并不能很好的解决,所以09年围绕着网络通信,内存持久化两个方面,做了大量的设计与论证。09年底左右推出新的服务TMEM。

核心有两点:
 提供内核级KCCD网络通讯组件,提升网络通信性能,在网络包量吞吐方面相对于应用层提升了接近1倍的性能。
 通过将操作流水加数据镜像落地TFS,解决了内存持久化的问题。
  TMEM的出现很好的满足了业务海量访问的需求。不过毕竟内存介质的成本比较高,所以TMEM在小数据量的场景下,性价比比较高。但针对于中大数据规模的海量访问的场景,使用TMEM的成本偏高,而使用SAS介质的TDB,则IO性能又不能很好的满足。比如社区中各类应用产生的Feeds,数据量数十TB至数百TB,每天访问量数十亿至数百亿,应对该场景传统的做法必须得是前端内存缓存加上后端落地存储。分级存储导致的内存数据保护,各级间数据一致性,另外最为关键的一点,与Social Game类似,Feeds也是典型交叉访问,热点不是非常明显,等等这些都是数据层亟需解决的难题。
四、【2010】顺SSD之势的TSSD
  在10年的时候,引入了SSD存储介质,开始构建TSSD K-V存储系统。SSD的特点:有着很好的随机读取性能,往往单盘可达数万IOPS,远高于SAS、SATA的数百随机IOPS。容量方面也接近SAS盘的容量,可达数百GB。但SSD也有弊端:(1)寿命有限,随机写入的寿命相对于顺序写入为1/10左右;(2)随机写入场景,性能易受干扰,毛刺率较高;具体而言:受限于物理机制,SSD的存储单元只能先擦除才能写入,并且擦除次数有限,针对NAND芯片,在3000~5000次左右。其中擦除单元是512KB,写入单元是4KB。随机写入的场景,会带来写入放大。
  因此应用SSD存储介质,必须优化随机写入性能。TSSD通过构建地址映射,增加随机写入内存缓冲区,实现随机转顺序的写入;通过定期的垃圾回收机制,回收垃圾数据。

  TSSD系统中,单机可以支持容量数TB,性能随机数万次IOPS。这样基于TSSD使用简单的架构,更少的机器便可支持到容量数十至数百TB,性能数十万IOPS的Feeds类应用。
五、NoSQL小结
  至此,业已构建出基于内存、SSD、SAS、SATA的各类存储介质的存储系统,在上面也已提到各类存储系统所对应的使用场景。实际应用中,各种业务场景千变万化,有没有统一的方法来判别和选择合适的存储系统呢?大致在 1987 年,Jim Gray发表了这个"五分钟法则"的观点,简而言之,如果一条记录频繁被访问,就应该放到内存里,否则的话就应该待在硬盘上按需要再访问。这个临界点就是五分钟。这个看似经验公式,隐含的是硬件性能和成本两个方面的因素。大约在97的时候,Jim Gray再次回顾了该法则,并引入了SSD,验证了该法则依然正确。这里不在赘述该法则。
  很多情况下需要一种直接根据业务的访问模型,因此使用IO访问密度,即每GB的存储的IO访问次数,会更为直观。那看看目前常用的几种存储介质:

SATA:希捷2TB/7200转/SATA(ST32000644NS)
SAS:希捷300GB/15000转/SAS(ST3300657SS)
SSD :Intel 160GB X25-M G2 34nm
DRAM:三星8GB DDR3 1333 REG ECC
(中关村在线报价,人民币美元汇率:6.3157,2012/4/16)
  根据业务IO访问密度,选择合适的存储介质,就是根据存储介质的IO访问密度特性与价格来选择性价比最高的存储介质,即找到每种存储介质之间IO访问密度的临界点。
  临界点G(X,Y).IO per sec per GB = X.IO per sec per GB * Y.price per GB / X. price per GB,X与Y分别表示对比的两种存储介质,且Y.IO per sec per GB 大于 X.IO per sec per GB。根据上面的公式,可以得到表格如下:

  怎么理解上面的公式呢?举计算SATA与SAS之间的临界点为例,G(SATA,SAS).IO per sec per GB = SATA.IO per sec per GB* SAS.price per GB/SATA.price per GB = 1/20 * 0.71/0.23 = 0.15 per sec per GB。假设现在有1GB的数据,访问密度是X,X小于2/3,那么使用SAS介质则需要0.71$,如果选择SATA介质,则需要X/(1/20) * 0.23 $。当X为0.15时,选择SATA与SAS的成本是一样的,当大于0.15时,则使用SATA的成本相对于SAS则高;否则则低。SAS比SSD,SSD比DRAM也是类似。
  实际上对于一款存储介质而言,IO访问特性与单位每GB的成本是决定了其存在与生命力的关键因素。通常来讲,其IO访问特性一般来讲不会有革命性的变化,而单位每GB的成本却是可以控制的,所以厂商总是会围绕容量来不断的深入优化。
六、开放的挑战
  10年底开始,随着开放的加剧,越来越多的第三方选择社交平台开发应用。这些外部条件的变化对技术平台的而言,也带来了新挑战:除需要为用户提供更强的海量服务外,同时还需要提供开放的软件基础架构来帮助第三方开发海量服务。现有已成熟的NoSQL的架构能否被外部第三方接受,其关键的一点是接口的友好性和兼容性。采用的标准化的接口,会大大降低外部开发者的使用门槛。因此,在11年推出了CMEM 的NoSQL云存储服务,开发者可直接使用memcached接口,并即将支持redis接口。同时也提供了SQL云存储服务,开发者可用MYSQL客户端直接访问。后续推出CFS文件系统云存储服务,开发者可使用posix接口访问到TFS。
  回顾TFS、TDB、TMEM、TSSD、CMEM、CDB、CFS等一系列存储系统过去近6个年头的演进发展。有两点经验可供分享:   1、 建议NoSQL开发者尽量选择构建PAAS服务。一方面对业务开发者而言,不需关心日常运维,使用更为方便,易于接受;另一方面更容易形成用户需求提出、实现与发布的闭环,从而方便小步快跑,快速迭代出完善的服务。   2、 建议中小业务开发者尽量使用云服务。通常一个NoSQL服务所面临的挑战有两个方面:一方面是大家所直观感受的产品本身;另一方面是服务背后的运营体系。类似与铁路系统、消防系统,用户所直观感受到的火车、铁路,消防栓、消防车只是整个服务其中一个部分,是冰山海平面之上的部分;用户所感受不到的铁路规划、调度系统、消防规划、消防演练,报警系统等后台运营体系通常是冰山海平面以下的部分,往往需要有大量的人力和财力投入,可能是中小公司难以投入的。而在没有稳固的后台运营体系支撑下,类似动车事故、火灾等生产系统故障难以避免,并最终为业务带来不可估量的损失。   从过去几年来看,硬件在变,存储介质的性能与容量在不断提升,并不断会有新存储介质的产生;业务在变,不断有新兴的产品和新的业务体验,并对后台系统提出新的挑战和需求;唯一不变的就是需要拥抱变化,为业务提供更贴切与更优化的存储服务。想了解更多关于腾讯TFS、TDB、TMEM、TSSD、CMEM、CDB、CFS等一系列存储系统过去近6个年头的演进发展,大家可以到腾讯大讲堂网站(djt.qq.com)翻阅架构平台部的分享文章,谢谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读752次。关系型数据库关系型数据库是一个结构化的数据库,创建在关系模型(二维表模型)基础上,一般面向于记录SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作主流的关系数据库包括Oracle、Mysql、SQL Server、Microsoft Access、DB2等非关系型数据库NoSQL(nOSQL=Not Only SQL),意思是“不仅仅是SQL”,是非关系型数据库的总称。除了主流的关系型数据库外的数据库,都认为是非关系型主流的NoSQ.._redis是非关系型数据库吗
文章浏览阅读687次,点赞2次,收藏5次。商城系统中,抢购和秒杀是很常见的营销场景,在一定时间内有大量的用户访问商场下单,主要需要解决的问题有两个:1. 高并发对数据库产生的压力;2. 竞争状态下如何解决商品库存超卖;高并发对数据库产生的压力对于第一个问题,使用缓存来处理,避免直接操作数据库,例如使用 Redis。竞争状态下如何解决商品库存超卖对于第二个问题,需要重点说明。常规写法:查询出对应商品的库存,判断库存数量否大于 0,然后执行生成订单等操作,但是在判断库存是否大于 0 处,如果在高并发下就会有问题,导致库存_php库存结余并发
文章浏览阅读1.4k次。MongoTemplate开发spring-data-mongodb提供了MongoTemplate和MongoRepository两种方式访问MongoDB,MongoRepository的方式访问较为简单,MongoTemplate方式较为灵活,这两种方式在Java对于MongoDB的运用中相辅相成。_springboot插入指定的mongodb数据库
文章浏览阅读887次,点赞10次,收藏19次。1.背景介绍1. 背景介绍NoSQL数据库是一种非关系型数据库,它的特点是可以存储非结构化的数据,并且可以处理大量的数据。HBase是一个分布式、可扩展的列式存储系统,它是基于Google的Bigtable设计的。HBase是一个开源的NoSQL数据库,它的核心功能是提供高性能的随机读写访问。在本文中,我们将对比HBase与其他NoSQL数据库,例如Redis、MongoDB、Cass...
文章浏览阅读819次。MongoDB连接失败记录_edentialmechanisn-scram-sha-1
文章浏览阅读470次。mongodb抽取数据到ES,使用ELK内部插件无法获取数据,只能试试monstache抽取mongodb数据,但是monstache需要mongodb replica set 模式才能采集数据。############monstache-compose文件。#replicas set 启动服务。# 默认备份节点不能读写,可以设置。# mydb指的是需要同步的数据库。#登录主mongodb初始化rs。#primary 创建用户。# ip地址注意要修改。# ip地址注意要修改。_monstache csdn
文章浏览阅读913次,点赞4次,收藏5次。storage:fork: trueadmin登录切换数据库注意: use 代表创建并使用,当库中没有数据时默认不显示这个库删除数据库查看表清单> show tables # 或者 > show collections表创建db.createCollection('集合名称', [options])table1字段类型描述capped布尔(可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。_mongodb5
文章浏览阅读862次。Centos7.9设置MongoDB开机自启(超全教程,一条龙)_mongodb centos开机启动脚本
文章浏览阅读1.3k次,点赞6次,收藏21次。NoSQL数据库使用场景以及架构介绍
文章浏览阅读856次,点赞21次,收藏20次。1.背景介绍1. 背景介绍NoSQL数据库是一种非关系型数据库,它的设计目标是为了解决传统关系型数据库(如MySQL、Oracle等)在处理大量不结构化数据方面的不足。NoSQL数据库可以处理大量数据,具有高性能、高可扩展性和高可用性。但是,与关系型数据库不同,NoSQL数据库没有固定的模式,数据结构也不一定是表格。在NoSQL数据库中,数据存储和查询都是基于键值对、列族、图形等不同的...
文章浏览阅读416次。NoSQL定义:非关系型、分布式、开放源码和具有横向扩展能力的下一代数据库。由c++编写的开源、高性能、无模式的基于分布式文件存储的文档型数据库特点:高性能、高可用性、高扩展性、丰富的查询支持、可替换已完场文档某个指定的数据字段应用场景:社交场景:使用mongodb存储用户信息游戏场景:用户信息,装备积分物流场景:订单信息,订单状态场景操作特点:数据量大;读写操作频繁;价值较低的数据,对事物性要求不高开源、c语言编写、默认端口号6379、key-value形式存在,存储非结构化数据。_nosql
文章浏览阅读1.5k次,点赞3次,收藏2次。Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: Failed to create socket. at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:110) at redis.clients.jedis.Connection.connect(Conne_redis.clients.jedis.exceptions.jedisconnectionexception: failed to create so
文章浏览阅读6.5k次,点赞3次,收藏12次。readAnyDatabase(在所有数据库上都有读取数据的权限)、readWriteAnyDatabase(在所有数据库上都有读写数据的权限)、userAdminAnyDatabase(在所有数据库上都有管理user的权限)、dbAdminAnyDatabase(管理所有数据库的权限);:clusterAdmin(管理机器的最高权限)、clusterManager(管理和监控集群的权限)、clusterMonitor(监控集群的权限)、hostManager( 管理Server);_mongodb创建用户密码并授权
文章浏览阅读593次。Redis是一个基于内存的键值型NoSQL数据库,在实际生产中有着非常广泛的用处_搭建本地redis
文章浏览阅读919次。Key 的最佳实践[业务名]:[数据名]:[id]足够简短:不超过 44 字节不包含特殊字符Value 的最佳实践:合理的拆分数据,拒绝 BigKey选择合适数据结构Hash 结构的 entry 数量不要超过 1000(默认是 500,如果达到上限则底层会使用哈希表而不是 ZipList,内存占用较多)设置合理的超时时间批量处理的方案:原生的 M 操作Pipeline 批处理注意事项:批处理时不建议一次携带太多命令。Pipeline 的多个命令之间不具备原子性。_redis高级实战
文章浏览阅读1.2k次。MongoDB 递归查询_mongodb数据库 递归
文章浏览阅读1.2k次。通过实际代码例子介绍:如何通过MongoTemplate和MongoRepository操作数据库数据_springboot操作mongodb
文章浏览阅读687次,点赞7次,收藏2次。首先欢迎大家阅读此文档,本文档主要分为三个模块分别是:Redis的介绍及安装、RedisDesktopManager可视化工具的安装、主从(哨兵)模式的配置。_redis 主从配置工具
文章浏览阅读764次。天下武功,无坚不摧,唯快不破!我的名字叫 Redis,全称是 Remote Dictionary Server。有人说,组 CP,除了要了解她外,还要给机会让她了解你。那么,作为开发工程师的你,是否愿意认真阅读此心法抓住机会来了解我,运用到你的系统中提升性能。我遵守 BSD 协议,由意大利人 Salvatore Sanfilippo 使用 C 语言编写的一个基于内存实现的键值型非关系(NoSQL)..._redis 7.2 源码
文章浏览阅读2k次。MongoDB 的增删改查【1】_mongodb $inc