面向数据系统的设计

数据分类

  • 业务数据
  • 索引数据
  • 计算数据

设计思路

在做数据库设计时应该考虑几个点
索引和数据分离
数据和计算分离

做面向CQRS的业务系统设计是和这个思路完美契合的

场景分析

当我们的传统的MySQL无法满足 多样化的查询需求时,我们一般会引入lucene,elastic search类似的搜索引擎
那么在设计时有个问题,是将业务中所有的数据都异构到搜索引擎中,还是只把索引字段的数据存储进去只查询出id

看似简单的选择后面其实会完全走向不同的设计

一股脑的把业务数据全部异构到搜索引擎里面,我能想到的优点就是

  • 依赖数据源只有一个,不需要回源数据
  • 代码实现简单

反之带来的问题

  • 索引构建频繁,业务中任何数据的变更都要同步到搜索引擎中
  • 吞吐量低

但如果采用数据回源的方案,优点我想到的如下:

  • 索引和数据分离,搜索引擎索引的数据量下来了,吞吐量大,可针对性的横向扩容
  • get by primary key操作对于任何数据库都是极快的,为了极致性能时,很容易针对性的做缓存优化
  • 更容易和DDD中聚合根结合起来
  • 修改索引时,对业务数据不影响
  • 计算和数据分离,数据和索引分离

实际案例选型

es在数据量很大的情况下(数十亿级别)提高查询效率
性能优化离不开filesystem cache,比如说你现在有一行数据。id,name,age …. 30 个字段。但是你现在搜索,只需要根据 id,name,age 三个字段来搜索。如果你傻乎乎往 es 里写入一行数据所有的字段,就会导致说 90% 的数据是不用来搜索的,结果硬是占据了 es 机器上的 filesystem cache 的空间,单条数据的数据量越大,就会导致 filesystem cahce 能缓存的数据就越少。其实,仅仅写入 es 中要用来检索的少数几个字段就可以了,比如说就写入 es id,name,age 三个字段,然后你可以把其他的字段数据存在 mysql/hbase 里,我们一般是建议用 es + hbase 这么一个架构。

hbase 的特点是适用于海量数据的在线存储,就是对 hbase 可以写入海量数据,但是不要做复杂的搜索,做很简单的一些根据 id 或者范围进行查询的这么一个操作就可以了。从 es 中根据 name 和 age 去搜索,拿到的结果可能就 20 个 doc id,然后根据 doc id 到 hbase 里去查询每个 doc id 对应的完整的数据,给查出来,再返回。