所有的技术方案都要从业务场景出发,不考虑业务场景,技术方案无意义。
业务场景:
1. 数据量为亿级,终极数据达到10亿。
2. 大数据团队可以导出当天的数据
3. 全部数据中的无效用户约为90%
4. 每次请求,均需要根据user_id判断是否是有效用户
5. 确认有效数据,需要从查询数据详情
下面看我们的迭代实现方案
一、业务初期
业务初期,数据量为几百万级,数据量较低,同时也意味着QPS较低,这种数据量下解决方案比较简单
1. 大数据把数据导入到业务数据库,mysql单表即可。
2. 业务请求过来,先读redis,不存在则直接读库
3. 读取到的数据缓存到redis,有效期为当天。
二、业务扩展,现状
该系统表现不错,现在其他业务线也要接入该系统,则现状即为本文开头的业务场景
解决方案:
1. 大数据把数据导入到业务数据库。数据分为全量数据和增量数据
a. 全量数据定期入库,例如每月更新一次
b. 增量数据每日更新入库,包括数据的新增,更改,失效等
2. 业务系统定时任务,从mysql里读取数据
a. 定期读取全量数据,在redis里面用布隆过滤器保存数据是否有效
b. 每日读取增量数据,更新redis的布隆过滤器
3. 因为绝大部分为无效数据,所以请求过来,布隆过滤器就可以判断该用户是否有效。无效数据直接返回。
a. 由于布隆过滤器是根据数据的hash存储的,所以极低概率下,存在hash值重复,即布隆过滤器可以判断数据一定不存在,不能判断数据一定存在。请判断你的业务需求是否要求数据严格一致性。
b. 要求数据严格一致性的情况下,则不使用布隆过滤器,可以聚合数据存储到redis。详细来说,这种情况下,判断数据是否有效,一般用标识ID来判断,比如user_id,product_id等等。而ID一般有规律性。比如如果你的ID为20位,则用前15位作为redis中hash集合(比如set)的key,后5位作为value。
PS:hash集合中的value数量,决定了hash集合的数据结构。默认1000以下为压缩列表,否则为哈希表。
4. 判断数据存在,根据qps,可选择读取数据库(可考虑是否分库分表),也可以选择把热点数据的详情存储到redis,redis中不存在时读取数据库
三、 10亿级别数据
10亿级别的数据,伴随qps的提升,无论是redis还是mysql,都具有很大的压力,有如下几个方向可供选择
1. 仍然采用上述的增量方案,判断数据的有效性采用布隆过滤器
2. 业务量的增长,同时也会带来数据有效性比率的增长,即有效数据的比例增加。判断完数据有效性后,主要问题在读取数据详情操作上
a. 仍采用把热点数据的详情存储到redis方案,需要redis有更大的内存,热点数据不存在时读取数据库
b. 数据库采用mogodb,直接读库
c. 引入分布式引擎elasticsearch。
es性能优化要点:
es要达到快速查询,也需要大内存,以便足够多的数据存储到Filesystem Cache.
数据预热,热点数据加载到Filesystem Cache
仅存储单条数据中的有效字段,缩小单条数据的数据量
从索引的角度,做冷热分离
不允许深度分页,不允许跳页
以上,可根据自己当前的技术栈,维护难度等来决策。