付钱拉 CTO 史晓慕
创业公司在业务上做一个支付模块的时候,首先要解决的是,如何建造一个高效、稳定、安全的数据库。而金融领域要求数据具有强一致性、系统具有高性能,在此基础上,如果再考虑上大数据,那问题就更复杂了。这里结合金融系统的数据库的研发经验,谈谈我眼中的金融大数据存储策略。
数据库的功能要考虑编程实现吗
如果不用数据库,可以通过自己编写程序实现吗?对应数据库都提供的五类功能,进行一一分析。
- 数据结构:表定义。【类、结构体都可以】
- 固化:数据落袋为安 。【序列化成文件,读时反序列化】
- RPC:提供远程访问接口。 【本地或远程函数调用即可】
- 锁:保证并发情况下数据的完整和安全。【程序里面锁机制很多,同步块、互斥变量等】
- 计算:各种联合,聚合函数 (sum、count、avg 等) 和存储过程 【自写逻辑,编写各种函数】
确实有一些数据比如树、图等非二维结构数据,用程序比用数据库,操作起来会更方便。但大部分情况下,完全自主实现上述五点难度很大,如果考虑上大数据下分布式部署、负载均衡、灰度发布、分布式锁等场景那就更复杂了。所以数据库的出现就是为了解决这些通用问题的。
随着数据量的增长,数据库的单机存储和计算能力也都会遇见瓶颈。如果应用重度使用联合,聚合函数和存储过程。分库分表的难度会非常大,需要使用非常复杂的数据库集群或中间件;性能还会大打折扣。所以我推荐轻度使用数据库,侧重数据结构和固化,不要让数据库做重度计算。锁机制最好也拿到外部去实现。
微服务架构下怎样管理好数据
数据库层层分解有这么几个维度:库、表、行。我们把数据的权限细化到表这个级别。如果仅有一个微服务模块有增加修改删除的权限,那这个模块就是这张表的主人。主人要负责维护好这张表,主人不要太多,多了要不然谁都不管,要不然就是互相打架。跨微服务模块读危害小于写,但也是不建议的,因为主人修改了表结构。读就会有问题,建议还是通过接口来。以上说的理想情况,实际场景请斟酌使用。
如果多个微服务模块同时操作一张表的一条记录,分布式锁的问题就不可避免了。除了使用悲观锁,还可以使用版本控制。为表增加一个状态字段,每个模块只操作符合自己状态要求的行。比如订单表的订单状态,入库模块是初始化状态,交易检查模块只操作初始化状态的行。交易拆分模块只操作检查完成状态的行,通过状态来实现数据的隔离。即是版本控制和状态的前置判断,也实现了有限状态机。涉及业务需要同时占有两个以上的独占资源时,会出现死锁。避免死锁的关键点是程序要按照统一的规则去给资源加锁。
数据更新操作可以采用先删除再增加的方法。增加操作是顺序 IO,一直在表的末尾追加。比起直接更新,这样做的好处是:性能优;不需考虑并发问题;可保存所有的历史版本。不过,这样做的弊端是数据量会成倍增长,程序实现逻辑也会更复杂。
如何控制数据的规模
一个系统的数据,会不断累计,变得越来越多。数据增长有快有慢,但不会凭空减小。考虑到数据节点的单机性能恒定,系统的整体性能会慢慢降低。如何控制单机数据的规模?如何平滑的增加存储计算节点?目前用的比较多的分库分表规则有两种:一种基于规则,一种基于配置。
比如根据时间规则,分割数据为日表、月表、在线库、离线库、历史库。如果时间不敏感根据主键取模或 hash,也是一个办法。由于规则是一定的,每次读写调用算法就知道数据的片区了。基于配置就是要把规则存起来,每次读写先要去读规则,这样才知道数据的片区。配置更灵活可变化,规则更简单,每种都有自己的场景。
因为篇幅的问题,有些话题我就不展开讲了,下次有机会我们详聊。
目录
专题|Topic
怎样打造一个分布式数据库
10 亿级流数据交互查询,为什么抛弃 MySQL 选择 VoltDB?
推荐文章 | Article
从单体架构迁移到微服务,8 个关键的思考、实践和经验
50 天 10 万行代码,一号专车系统重构细节回顾
京东前端:三级列表页持续架构优化
观点 | Opinion
怎样才能叫高级程序员?
评论