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

京东分布式存储建设之路

时间:2023-03-13 00:56:41 科技观察

一拍即合,京东分布式存储扬帆起航你在项目中经常遇到,有一些图片、视频或文字需要存储,希望不要丢失,在同时提供高速读写能力。对于京东来说,这样的需求每天都在发生,而且要求会更高,因为这些可能是用户的订单数据,你希望即使写的时候断电或者磁盘坏了,你的数据还在那里;你希望即使服务器出现故障,交换机坏了,或者机房宕机了,用户仍然可以正常访问;你希望即使大促来临时用户访问量翻倍,仍然可以提供高速读写。没错,现在很多人会告诉你,使用JFS京东文件系统就可以满足你的需求。时间回到2013年,海峰刚来京东。他很快发现,京东对存储的需求非常强烈,既有海量小文件的在线存储,也有离线数据存储。它做得不好。各个业务部门各司其职,很多都慢慢开始不能满足业务增长的需要。他灵机一动,决定为京东打造一个统一的分布式存储平台,满足公司各条业务线的需求。还有一个只有6、7个人的小型仓储团队。虽然工作年限普遍不长,也有刚毕业的,但都想在存储方向有所建树。怀着同样的愿景,大家很快就走到了一起。在海峰哥的带领下,系统技术部存储组正式成立,开始了京东分布式存储的研发。从2013年到2016年,整整做了三年。那个时候,小鲜肉成为了公司存储方向的骨干,成为了存储专家。JFS也成为了京东业务的核心底层存储,支撑着公司1000多家企业。商业。一路走来,踩过不少坑,也有一些心得,分享给大家。艰难抉择,分布式存储技术选择京东有多种数据存储需求。有10KB大小的订单数据,每天以1亿以上的速度增长;有90k-200k大小的图片数据,总数超过十亿。而且每天还在以几千万的速度在增长;还有几十兆的App客户端文件,每次更新都伴随着海量的用户访问量;还有1GB甚至10GB以上的内部日志文件存储。各个业务部门使用的存储方式也是五花八门,比如Mysql的Blob类型存储,还有开源的FastDFS和Hdfs。诚然,这些软件对京东的快速发展起到了至关重要的作用,但随着业务规模的不断增长,各种问题也开始暴露出来。摆在我们面前的路有两条:一是在开源系统的基础上做定制开发,二是自主开发。这两种方法各有优缺点。最后,经过多方研究,我们决定走自研之路。这里我们以知名的Hdfs及其生态为例,回顾一下当时的决策过程。毫无疑问,Hdfs是一个非常优秀的开源存储项目,但它毕竟是为离线大文件设计的,对付京东海量的在线小文件无能为力。二次开发需要对整个架构进行手术。另一个考虑是用Hdfs存储大文件,用HBase存储小文件。当然,这个方案并不适合京东。主要有两点:***,HBase读取文件时,先向RegionServer发送请求,RegionServer从Hdfs中取数据,然后返回,相当于经过两次IO请求,这不是适用于很多追求极速的应用场景;第二,HBase做Split的时候,服务会暂时不可用,这对于很多需要7*24小时不间断服务的应用业务来说更不可接受。自主研发的周期虽然会长一些,但灵活可控,从长远来看,也可以获得技术收益。昼夜开灯,JFS小文件存储大厨就位,菜已经洗好,下一步该从何入手。京东的统一分布式存储做起来非常困难,因为即使是现在,也没有开源的方案可以同时支持海量在线小文件和离线大文件。庆幸的是,当时我们并没有选择一步到位的全面解决方案,而是紧扣业务,高度定制化,分阶段开始这条路。小文件存储被选为餐桌上的第一道菜。无论是商品图片、交易订单,还是仓库订单,这些电商数据都需要非常强的可靠性、可用性和一致性。在复制协议中,我们采用了三副本强一致性复制,由1Primary+2Followers组成,如下图所示。写操作时,client向master发送数据,master同时向两个slave副本发送数据,三个副本写入成功后才返回给用户。读的时候,从第一优先级开始读,提高系统的并发度。在数据存储方面,考虑到文件比较小,如果用户上传一个文件,并在服务器上相应的创建一个文件来存储数据,那么2T的磁盘上会存储几千万甚至上亿的文件,会给服务器带来沉重的负担。负担。我们预先建好一个大文件,然后不断追加写入,使用offset和size访问数据。当然,为了避免单个大文件集中读写导致的文件锁资源的激烈竞争,我们采用了多文件追加的方式,如下图:现在记不清有多少了日日夜夜我都在加班。因为我们很熟,小姑娘会故意多给我们夹菜;年轻的队员们白皙的脸上有黑眼圈。终于,时隔4个月的一天,我们迎来了第一个孩子,京东小文件存储系统终于正式落地。当然,也没有让大家失望。在与同类开源软件的对比测试中,性能等指标更胜一筹。一个新系统的推广总是很困难的。一开始,我们开始推广到一些非核心业务的数据存储,逐步应用。当然,我们也一直在为一条大鱼的到来做着准备。小试一下,京东的新形象系统可以追溯到2014年,老员工可能还有印象。随着图像数据量和访问量的急剧增加,老旧的图像服务已经达到了性能瓶颈。客服每天都会收到大量用户投诉图片访问慢、IO异常、数据多副本不一致等问题。报警邮件几乎占满了相关业务部门的邮箱。老图系统可以追溯到多年前,当时也是选择了业界广泛使用的开源存储方案。最开始一两年是没有问题的,但是随着数据量的暴增,各种问题开始暴露出来。一开始,业务部门可以通过修改配置,增加一些缓存策略来解决问题。后来这些根本不管用,需要优化整体的存储架构。这时JFS在一些非核心业务上获得了不错的口碑,于是图片业务部门找到我们,希望将图片业务迁移到JFS。时间来到了2014年4月,距离京东上市只有一个月的时间。我们需要开发一个新的基于JFS存储的图片系统,需要在不影响现有业务的情况下完成20亿历史图片的迁移。大家都知道其中的巨大风险,但是没有经过太多复杂的权衡,我们很快就同意了。接下来就是与时间的赛跑。组员们迅速分工。几位同事花了一周的时间完成了新图像系统的搭建。又用了三周的时间,完成了全部20亿存量数据的迁移和校验。终于在公司上市前夕,完成了新旧图片系统的切换,彻底解决了图片访问慢的问题。京东的图片规格很多,同一张图片可能有10多个不同的规格,所以我们只在源站存储一张原始图片,CDN没有专门的图片回源站做真实-时间压缩,既节省了存储空间,又满足了业务不断变化的需求。如下图所示:当然,在解决了核心的图片存储和简单的图片处理之后,我们也做了一些工作来推动京东图片技术的发展。在缩放效率方面,我们与英特尔紧密合作,通过代码重构、ICC编译、IPP编译等方式,将图像缩放速度提升至原来的3倍以上。2014年,我们创新性地将图片Webp格式引入京东,并与无线部门紧密合作,将移动端的图片全部替换为Webp格式。整体图片体积缩小50%,为CDN节省30%的流量,为用户节省庞大的下行流量,让用户访问速度更快,大大提升用户体验。继续说下去,JFS大文件存储也是单客户端大文件上传下载性能的一个重要指标。小文件复制协议1Primary+2Followers方式已经不是最好的方式了。Primary拿到数据后,同时发送给两个slave副本。这样Primary的带宽资源就会成为系统的瓶颈。因此,在大文件存储复制协议的选择上,JFS采用链式复制,最大限度地利用系统带宽资源。链式复制结构如下图所示。在数据发送和接收方面,我们采用了流式处理,大大提高了大文件的传输效率。在数据存储方面,与小文件正好相反,我们将一个大文件分成多个块进行存储,可以避免局部过热的文件导致单机磁盘IO过载。同时,分成多个区块也更有利于系统整体资源的利用。调度。发展迅速,京东对象存储前面的小文件存储和大文件存储在可靠性、易用性和稳定性上已经满足了大部分业务需求,但是使用起来不是很方便,上传下载需要通过SDK,用户排查问题不是那么方便,对多国语言的支持也不好。接下来我们针对亚马逊的S3产品形态。简单对象存储,支持Http协议;支持存储文本、图片、视频等任意类型的数据;支持1字节到1TB的数据存储;支持列表操作,用户数据可以有层次结构。这很适合京东这种业务场景多、应用复杂的情况。因此,我们决定在JFS上构建对象存储,为用户提供更方便的访问。对象存储由几个部分组成。除了我们已经提到的大小文件存储之外,还需要搭建Gateway、账户和Bucket管理、日志处理等,当然还有最复杂的元数据管理。对象存储的元数据管理是业界的难题。对象存储虽然没有目录的概念,但必须支持通过前缀进行List操作,即通过Prefix和Delimiter的结合,实现分层查询。当数据量不大时,类似于Hdfs的NameNode可以通过将所有用户key存储在内存中来满足需求,但是当对象数量超过亿或十亿时,内存就会被耗尽,无法实现水平扩展。很多KV存储可以随意扩容,但是不能很好的支持对象存储List请求。我们的方案不是一个完美的方案,但是已经可以满足京东百亿级别的元数据管理,放在这里供大家讨论。我们采用Mysql+Jimdb(京东自研的高速KV缓存系统)将元数据扁平化持久化到Mysql中,同时利用Mysql的B-tree结构实现元数据的List级查询。使用Jimdb作为缓存提供高并发。当然,只有Mysql不能实现水平扩展。我们在Mysql之上搭建了自动化的分库分表系统ET,可以在不影响业务的情况下实现Mysql的拆分和在线数据迁移。如下图所示:正常情况下,Client直接连接对应的Mysql复制组。当某个组的Mysql记录数达到一定限度时,Manager触发拆分,启动一个Migrator作为Mysql代理,与Manager紧密配合完成实时数据处理和历史数据迁移。对象存储一经推出就受到了业务部门的广泛欢迎。目前已支持京东1200多条业务数据的存储。双十一的峰值是每秒同时实时读写25000个对象,存储的对象达到数百亿。数据量超过10PB。不断创新,电子票据后台系统中电子票据的存储是对象存储的一个重要应用。京东每天有数百万的订单。过去,每天有数百万张纸质收据被保存和堆积在仓库里。当发生纠纷时,需要从数以亿计的纸质收据中找出用户当时签收的收据。这无疑是一项繁琐、耗时、成本高、不环保的工作,大大增加了京东物流的管理成本。运营系统青龙研发部从环保和成本角度出发,创新性地提出使用电子收据。整个电子票据产生的海量签名图像需要进行高安全性、高稳定性、高耐久性的存储。并且根据国家快递管理规定,物流签收保存一年,财务签收意味着系统需要能够存储上百亿张用户签收图片。海量的数据存储也给青龙的研发带来了一些困难。这对于对象存储来说无疑是一个很好的应用场景,但是其自定义加解密、文图转换、图片合成等也对对象存储提出了更高的要求。为了更好的支持业务创新,我们开发了基于对象存储的电子票据后台系统。可根据接收到的签到信息,按照指定样式生成签到回执图片,并与用户签名图片合成;根据业务对安全性的高要求,对数据进行加密存储,保障用户数据的绝对安全;加密后通过POS机发回数据解密后在用户查看时显示给用户。初衷没有改变。JFS小文件和大文件存储的JFS统一存储的实现,已经能够解决京东大量的应用场景。但它离我们一个团队,一个存储的愿景还很远。接下来我们开始了小文件和大文件存储的整合。对于同一个三副本强一致性复制,我们统一了复制协议,兼顾小文件和大文件的性能,采用链式复制。在文件存储方面,大小文件的处理方式不同,不能强行统一。因此,我们使用大文件存储和小文件存储作为不同的可插拔存储引擎来管理集群中不同类型文件的存储。面向未来,京东分布式存储展望未来,我们还计划让JFS支持共享存储,可以直接挂载到容器上。这样,应用的非结构化数据直接存储在分布式存储上,减少了日志等数据先存储在本地磁盘再收集到分布式存储上的需求。同时,与容器技术更紧密的结合也支持了容器故障的快速调度和转移。【本文来自专栏作者张凯涛微信公众号(凯涛的博客)公众号id:kaitao-1234567】点此查看作者更多好文