新思潮:NoSQL与DPDK、RDMA等会擦出什么样的火花?
编者按:NoSQL发展到今天虽然在技术和生态上已经非常成熟,但是并没有停止演化,尤其是在一切都容器化、微服务化的大背景下,很多NoSQL产品也在拥抱Docker,在硬件和系统技术栈上,新技术也是层出不穷,如用户态TCP/IP协议栈、DPDK、RDMA等,这些技术和NoSQL结合之后会擦出哪些火花呢?本文就容器化的典型例子AeroSpike和技术全面领先的ScyllaDB做大概介绍。
在新技术层出不穷的背景下,NoSQL也在努力求变,今年大会有几个新的演变方向,分别是:
容器化:将NoSQL产品与Docker相结合,然后收获容器的诸多益处如运维简单、开发更加规范、封装和隔离更为彻底,其中的主要难点是容器更适合stateless的服务,而NoSQL是带数据的,如何做到stateless是个很大的挑战,而且NoSQL对时延的要求很高,容器带来的损耗也是需要考虑的一个问题。
软硬一体优化:将 网卡->CPU->TCP/IP->工作线程->文件系统->IO存储 这一整条链路的每个环节都做极致的优化,该优化的大背景是NoSQL每次操作都是500us-1ms级别,但是用于业务数据处理的时间可能只有10us左右,整个链路的成本已经远远超过了数据处理的成本,所以下一步的优化的方向只能从链路着手,在网卡层面利用RDMA技术,在CPU层面采用多核+线程亲和性+NUMA等特性,在TCP/IP层面采用DPDK+用户态协议栈技术,在工作线程层面采用shared nothing的无锁架构,在文件系统层面采用一些比较新的文件系统如XFS,有的NoSQL产品甚至bypass了文件系统,直接操作设备,存储方面采用NVME或者SSD。
云化:自己不再持有很重的IDC资产,直接根据客户需求在云上灵活部署和弹性伸缩,轻资产的模式让自己专注于技术和业务创新。
NewSQL化:开始关注ACID、CAP,不断向传统数据库的特性靠拢,与传统数据库之间的共同点也会越来越多,毕竟大家面临的分布式问题都是一致的。
AeroSpike作为高性能的NoSQL服务,已经有近3年的历史。NoSQL领域产品众多、滥觞成河,AeroSpike绝对算其中一朵奇葩,在很久之前就进行了很多前沿性的探索,比如在存储上采用混合架构,采用RAM+SSD的架构,其中索引存储在RAM中,数据存储在SSD中,并且是直接访问SSD,bypass了文件系统,然后又针对多核处理器的体系架构特点做了优化,因此能带来性能的极致优化,声称比友商高出10倍以上(当然我没有亲测过:-),而且在很久之前AeroSpike就实现了集群的分片、自动负载均衡、多数据中心同步等高级功能,这是目前很多NoSQL产品还在努力struggle的特性。
AeroSpike容器化遇到的挑战有:
1,数据冗余:要求至少大于1个副本,容器允许随时失效2,数据库集群的自治与服务发现:允许容器节点随时加入和退出
3,数据库自我修复:允许容器节点随时加入和退出
4,应用层感知数据库集群:需要有个服务发现机制
5,对原有架构挑战:原来基于物理机的架构都需要调整,不止是简单的换个皮而已,从复杂度、可维护性、持久化、一致性、可扩展性、成本、性能等维度都面临着新的挑战;原有的部署和运维架构也受到冲击;原有的很多优化方法也受到容器的挑战;
6,哲学层面:容器是被设计来用于解决封装、隔离、部署问题的,数据库是被设计用于持久化、可扩展、自治自修复的,这两种设计如何match到一起也是个挑战
针对上述挑战,AeroSpike的解法是:
1,数据冗余:数据是多副本的,而且副本数量可以配置
2,集群自治与服务发现:集群所有节点share nothing,都是对等的,采用Docker Swarm方案
3,数据库自我修复和负载均衡:采用hash分片,而且设计了RIPEMD-160算法来保证高效的分片
4,应用层感知数据库集群:采用Smart Client来做集群的自动感知
5,对原有架构挑战:主要是对数据如何存放的挑战,数据和容器放在一起虽然也能保证随时加入和退出,但是不如把数据彻底剥离到宿主机或者云上的共享存储如EBS中更优雅,而且更近一步是否可以剥离出单独的一种容器叫做Data Container,只用来管理数据,策略可以做得更复杂,比如在销毁的时候可以做一部分业务逻辑在里面。还有一个更大的挑战是性能问题,在本次介绍中主讲人并没有给出彻底的解决方案,应该是还在优化中
6,哲学层面:总结一下还是数据库去适应容器的特点,把数据库做成了一个无状态、可随时加入退出、能够做到自组织自发现自修复的系统,使数据库表现起来也像个“容器”
最后AeroSpike列出了容器化带来的收益,比如:开发和生产环境能更统一,运维更加简单,scale up和scale down做起来比之前更容易一些,等等。
接下来ScyllaDB的CTO分享了ScyllaDB在极致性能优化上的实践和经验总结,ScyllaDB是一个兼容Cassandra协议的分布式NoSQL数据库,在相同的硬件条件下能比原始版本的Cassandra性能提升10倍左右,使用C++14编写,纯异步,整个编程框架是Seastar,可以理解ScyllaDB是在Seastar框架基础上的Cassandra协议实现。
ScyllaDB设计理念/High levels是:
1,更有效率:相同时间内干更多的事情
2,释放整机能力:榨干整机每个部件的能力
3,更可控:控制何时何处使用计算能力
面临的问题是:
1,太多的微操作:尽量让协同成本变得更低
2,太多通信行为:本机内、与其他机器、与disk通信
而且在计算机的最底层就是一个异步的架构,如Intel CPU的流水和指令执行过程就是一个异步过程,在有了上述抽象之后ScyllaDB的设计架构为:
1,每个CPU Core都有一个绑定的线程,可以做到永远不会阻塞
2,网络操作是异步的
3,文件I/O是异步的
4,每个核上都是异步的
在传统的架构中,系统中有多个线程,每个线程都有自己的堆栈和上下文,线程切换造成的开销和CPU cacheline的污染非常严重,在微操作频繁的NoSQL数据库中,这部分切换带来的开销其实是非常大的,Seastar框架是每个core一个native thread,然后每个thread中用Task和Promise来抽象工作任务,Task是一个c++ lambda表达式,promise是用来保存计算结果的指针。
在做性能优化时有一个基本的公式是:
Concurrency = Throughput*Latency
这么看起来不大好理解,但是变形之后就比较好理解了,如:
Throughput = Concurrency/Latency 所以当追求吞吐量时,在一定延迟下需要并发尽量大
Latency = Concurrency/Throughput 所以当追求延迟时,在一定的吞吐下需要并发度尽量低
为了压榨机器的性能,我们一般要求机器的每个资源能够有很好的并行性
在做资源调度时,Seastar抛弃了操作系统的各种调度器,改由自己全面接管,比如当做I/O时,Seastar禁用了Linux的I/O调度器,在Seastar看来系统调度器只能看到产生I/O的线程的优先级,无法看到整体的优先级,而且系统调度器会有很多额外的reorder和merge操作,而且Seastar的I/O调度器还能感知到一个最佳的并行度,当并行度增加但是吞吐并不同比增加时没有必要再增加并发。对于文件的缓存直接复用Linux的page cache,因为做得已经足够好。下图是ScyllaDB中的调度模型:
Seastar对内存分配也做了很多优化,主体思想就是将需要的内存提前分配出来,尽量不要走到系统的malloc/free,为了降低碎片也做了很多分配策略。
最终提到了对于RDMA+DPDK+User Space TCP/IP的使用,这也是一个很大课题,以后另开文章详细剖解,主讲人认为目前还不够成熟,最好不要用于生产环境,另外ScyllaDB还从query编译优化(将查询直接编译成代码)等角度做了优化。
从上述这两个例子中我们大概勾勒出一个未来的NoSQL产品大体是这个样子的:
1,集群化,多副本,每个副本可以随时失效,可弹性伸缩,节点可以随时加入和退出
2,可以与容器完美结合,降低开发、部署、运维成本
3,将在内核态的计算完全转移到用户态并做极致优化,如对传统线程的lambda抽象、自主可控的调度器、bypass文件系统直接操作裸设备、使用用户态协议栈来大幅削减网络链路成本等
4,在功能上逐步向传统数据库看齐,如支持事务、支持ACID等特性,催生出NewSQL
5,能够方便云化以触达客户
这个世界变化太快,一不小心就会被狠狠抛弃,是每一个码农的幸运也是不幸,痛并快乐着,引用主讲人的最后一句话“While having a lot of fun”。