《架构师》2016年9月
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

卷首语:谈大数据存储

创业公司在业务上做一个支付模块的时候,首先要解决的是,如何建造一个高效、稳定、安全的数据库。而金融领域要求数据具有强一致性、系统具有高性能,在此基础上,如果再考虑上大数据,那问题就更复杂了。这里结合金融系统的数据库的研发经验,谈谈我眼中的金融大数据存储策略。

数据库的功能要考虑编程实现吗

如果不用数据库,可以通过自己编写程序实现吗?对应数据库都提供的五类功能,进行一一分析。

1.数据结构:表定义。【类、结构体都可以】

2.固化:数据落袋为安。【序列化成文件,读时反序列化】

3.RPC:提供远程访问接口。【本地或远程函数调用即可】

4.锁:保证并发情况下数据的完整和安全。【程序里面锁机制很多,同步块、互斥变量等】

5.计算:各种联合,聚合函数(sum、count、avg等)和存储过程【自写逻辑,编写各种函数】

确实有一些数据比如树、图等非二维结构数据,用程序比用数据库,操作起来会更方便。但大部分情况下,完全自主实现上述五点难度很大,如果考虑上大数据下分布式部署、负载均衡、灰度发布、分布式锁等场景那就更复杂了。所以数据库的出现就是为了解决这些通用问题的。

随着数据量的增长,数据库的单机存储和计算能力也都会遇见瓶颈。如果应用重度使用联合,聚合函数和存储过程。分库分表的难度会非常大,需要使用非常复杂的数据库集群或中间件;性能还会大打折扣。所以我推荐轻度使用数据库,侧重数据结构和固化,不要让数据库做重度计算。锁机制最好也拿到外部去实现。

微服务架构下怎样管理好数据

数据库层层分解有这么几个维度:库、表、行。我们把数据的权限细化到表这个级别。如果仅有一个微服务模块有增加修改删除的权限,那这个模块就是这张表的主人。主人要负责维护好这张表,主人不要太多,多了要不然谁都不管,要不然就是互相打架。跨微服务模块读危害小于写,但也是不建议的,因为主人修改了表结构。读就会有问题,建议还是通过接口来。以上说的理想情况,实际场景请斟酌使用。

如果多个微服务模块同时操作一张表的一条记录,分布式锁的问题就不可避免了。除了使用悲观锁,还可以使用版本控制。为表增加一个状态字段,每个模块只操作符合自己状态要求的行。比如订单表的订单状态,入库模块是初始化状态,交易检查模块只操作初始化状态的行。交易拆分模块只操作检查完成状态的行,通过状态来实现数据的隔离。即是版本控制和状态的前置判断,也实现了有限状态机。涉及业务需要同时占有两个以上的独占资源时,会出现死锁。避免死锁的关键点是程序要按照统一的规则去给资源加锁。

数据更新操作可以采用先删除再增加的方法。增加操作是顺序IO,一直在表的末尾追加。比起直接更新,这样做的好处是:性能优;不需考虑并发问题;可保存所有的历史版本。不过,这样做的弊端是数据量会成倍增长,程序实现逻辑也会更复杂。

如何控制数据的规模

一个系统的数据,会不断累计,变得越来越多。数据增长有快有慢,但不会凭空减小。考虑到数据节点的单机性能恒定,系统的整体性能会慢慢降低。如何控制单机数据的规模?如何平滑的增加存储计算节点?目前用的比较多的分库分表规则有两种:一种基于规则,一种基于配置。

比如根据时间规则,分割数据为日表、月表、在线库、离线库、历史库。如果时间不敏感根据主键取模或hash,也是一个办法。由于规则是一定的,每次读写调用算法就知道数据的片区了。基于配置就是要把规则存起来,每次读写先要去读规则,这样才知道数据的片区。配置更灵活可变化,规则更简单,每种都有自己的场景。

因为篇幅的问题,有些话题我就不展开讲了,下次有机会我们详聊。

付钱拉CTO 史晓慕