在传统IT应用程序设计中,application本身并不负责数据的持久化存储。数据要持久化存储,就考虑种种软件的健壮性和性能的种种问题:
- server restart后,如何保证数据的一致性(redolog问题)?
- 要考虑数据存储的二进制格式,压缩解压,要考虑cache的替换策略
- 如何查找速度更快,是否需要创建冗余数据加速查找(查询优化,索引)。
关系数据库从上世纪70年代发展到今天,其功能越来越复杂。外键约束,触发器,物化视图,存储过程,等特性接踵而至,关系数据库的霸主oracle推出的PL/SQL的编程语言,开发者之需要编写脚本的方式开发应用程序。然而,功能强大的rdbms,却很难满足互联网时代的海量用户的并发需求。先分析下大致的几个原因
- 大部分关系库都是磁盘数据库,磁盘的随机IO往往是系统的最大瓶颈,SSD远没普及;memory也很小,10年之前4G的物理服务器memory已经不小,OS还是32位。
- 关系库为了实现ACID,设计过于复杂,在x86-scaleout为王的互联网时代,关系库很难做成分布式
由于数据库的重要性,解决性能瓶颈问题也一直是服务端互联网技术发展的核心问题。大致有这么几个思路
- 最常用的手段是在数据库前面加一层分布式缓存,例如redis/memcache。加db缓存的方法主要的思路是把热点内容缓存到内存中,一台数据库服务内存不够,就用多台服务的内存加起来可以做一个大的内存池。这种做法需要结合具体的业务场景, 应用深度切入,哪些数据能缓存,哪些不能,数据丢失后如何补偿,如何进行持久化等等都需要业务通盘考虑
- 单机的硬件加速,db主机加内存,存储换成pcie-ssd/全闪存阵列,单卡的pcie-ssd,4k-随机读写iops提升到100K+。cpu的摩尔定律虽然已经结束,但是硬件的技术革新并没结束,GPU、3d-xpoint代表着新的技术发展方向。
- 软硬件结合的一些数据库一体机方案,数据库一体机的概念大概在3、5年前比较火。当然一体机水平参差不齐,不过作为一种approach是work的。例如fusionIO的pxessd卡,支持atomic write,相应的mysql写性能有百分之几十的明显提升。
- 放弃关系模型,重新定义data model,这是nosql的方案。例如dynamo/cassandra/riak/mongodb。NoSQL的数据模型更为简单,功能也更为简单,天生适合scale-out。
- 在现有的rdbms基础上,做一些有约束的scale-out。例如读写分离,分库分表。分库分表可在业务上做,但耦合性强,常见的做法是一些支持data sharding的数据库中间件,例如proxysql,mycat等。
- 对于写性能要求比较高的场景,可以考虑更换存储引擎,用lsm-tree等写优化的数据结构替换B树,例如mysql的myrocks,tokudb等。
- 最后要提的就是scale-out first,实现一个新型的分布式的rdbms,这就是newsql。newsql技术流派更多,目前在云数据库领域比较热门,也是经过大规模生产环境证明的方式,大概有前2个:
- google spanner方式。首先整个分布式数据库构建在一个底层的分布式存储引擎上,一般是kv方式,不同节点间通过raft/paxos做数据的复制。SQL层通过2PC+2PL实现分布式事务,支持MVCC,事务冲突可以是硬件时钟,也可以是软件时间戳。开源的实现是TiDB,cockroachdb。
- amazon aurora方式。计算引擎仍然用传统荣rdbms内核。存储引擎是一个重新实现的分布式存储,主从节点之间通过raft/paxos同步日志,本节点的存储引擎从同步到的日志中恢复data block。读性能线性扩展,写性能只能发生在主节点,但并非受限于主节点的存储IO,而是主节点的网络带宽。目前阿里云的polardb也是类似的方式。
- 其他的newsql,voltdb,memsql,nuodb,clutrix,sap hana
总而言之,最近三五年的时间,传统数据库领域出现了很大变化,一方面受益于硬件的发展,更重要的原因可能是云时代的到来。大家有兴趣可以看下CMU的一片关于newsql的文章,对于近些年互联网行业数据库技术的发展做了详细的总结和展望。
http://db.cs.cmu.edu/papers/2016/pavlo-newsql-sigmodrec2016.pdf
http://db.cs.cmu.edu/papers/2016/pavlo-newsql-sigmodrec2016.pdf