如果有十几亿白名单,每天白天需要高并发查询,晚上需要更新一次,如何设计?..._缓存

首先要明确,几十亿白名单,数据量有多大?是否存储在一个数据库中?要不要数据分片?未来数据会不会增加,增加会以怎样的趋势进行?

高可用上有什么要求,是否需要多活容灾?

其次高并发有多高?查询是单独的查询还是有关联关系?是否有热点数据?

从问题描述来看,这是一个典型的读多写少场景,可以在数据前加一层NoSql缓存来优化查询效率。具体NoSql中如何组织数据需要根据查询条件来设计。

还要考虑的一个问题是,更新缓存的时候还会有查询请求吗?请求对数据的实时性要求高不高?如果真如问题描述,白天请求,晚上更新,假定有一个界限来区分白天和晚上的话,那么大可放心大胆的先更新数据库,再从数据库中取数据更新缓存,没有查询请求,这中间的数据不一致就没有任何影响。

如果你更新的同时还是会有数据请求进来,那么就会有些棘手。你需要对命中的缓存判断有效性,是否在数据库中已经更新?如果更新了要不要从数据库中同步?同步的话查询效率降低对客户会产生多大的影响?

存储问题

数据如果已经存储在比如mysql中了,但是还没有做数据分片,读写性能低,那就要看要不要做分库分表或者直接迁移到nosql进行存储。如果数据还没有进行存储,那就直接考虑先从数据库选型开始。

数据库选型要考虑扩展性、数据一致性要求、过往技术栈、运维支持能力、是否需要关联查询等。

如果是开发团队自己开发自己运维。如果数据量大,并且还在持续增加,数据一致性要求不高。像白名单这种场景,如果基本没有什么关联查询,mangodb单表可以承载PB级别的数据量,比mysql更合适。分布式关系型数据库从我目前调研的情况来看,真正使用到核心业务的公司并没有那么多。涉及到技术成熟度等一些问题。比如不管是TiDB还是OceanBase只能支持两地三中心(OceanBase号称可支持三地五中心),不支持三地六中心的架构。

并发查询问题

并发查询量如果都是简单的类似于key value的简单查询,mangoDB本身就能达到非常高的并发量。具体还需要了解咱们这边响应时间的指标。如果有热点数据,还可以考虑是否需要redis缓存来处理。

这里要提一个问题:就是在上面解决存储问题的时候,为什么不直接使用redis来做存储?像白名单这种简单数据结构,用redis似乎也很合适。但是很少有人直接拿redis作为最终数据源。原因就在于首先即使本身数据的结构非常简单,但是出于运维、追踪等的需要,还是需要一些额外信息,比如:状态、创建时间、更新时间、更新人等,这就不简单是key value。

更新问题

更新时会遇到数据一致性的问题。在这方面有没有特殊要求,比如:允许用户延迟看到数据更新后的结果,但是不允许用户三笔请求过来,一笔请求返回了更新前的,一笔返回了更新后的,下次必须返回更新后的,再返回更新前的就不被允许。如果没有这种要求,并且本地内存空间也允许,可以考虑将少量热点数据加载到本地内存来提高读并发性能。

而对数据一致性要求比较高的话,那可以写的时候先加一个分布式锁,删除缓存数据,并更新数据库后更新缓存。这段时间有查询请求,如果查不到数据就等待直到获取到数据或者超时。