面向数据系统的设计
数据分类
- 业务数据
- 索引数据
- 计算数据
设计思路
在做数据库设计时应该考虑几个点 索引和数据分离 数据和计算分离
做面向CQRS的业务系统设计是和这个思路完美契合的
场景分析
当我们的传统的MySQL无法满足多样化的查询需求时,我们一般会引入Lucene,ElasticSearch类似的搜索引擎 那么在设计时有个问题,是将业务中所有的数据都异构到搜索引擎中,还是只把索引字段的数据存储进去只查询出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 对应的完整的数据,给查出来,再返回。