一份文档被索引之后,需要等待一段时间才能被查询到。这一性质维护了 es 的性能承诺,但也限制了它的应用场景。截至本文撰写之日,es 已经更新到了 7.x 版本。然而,网络中几乎查询不到将其用作企业级主力搜索赋能工具的案例,也许大家选择了 RMDB,亦或是技术保密吧。
环境设定
假设,我们接到一项任务,将 RMDB 切换为 NoSQL 。其中,指定 es 为搜索引擎,指定一款仅包含主键索引的数据库来存储数据,kv/column/graph 数据库可以作为辅助工具。不考虑分布式一致性问题的前提下,如何去解决延时问题呢?
独立搜索场景
如果一个搜索请求是独立的,也就不存在因果关系。发起者对结果集的大小是没有预期的,通常情况下可以接受索引延迟。
非独立搜索场景
UI 交互场景
当用户新增了一条数据,刷新列表,期望看到新增的数据。
-
等到索引可见后,再响应新增请求。可以通过 sleep 命令等待 1s,或者在 es 请求中设置
?refresh=wait_for
-
在处理列表请求时,等待 1s
-
对于未设置搜索条件的列表页,使用 redis 缓存最近新增的数据。并在组装列表数据时,添加这些缓存数据
后台程序 write_and_read 场景
过程 P2 希望搜索到前一个过程 P1 写入的数据。
-
P1 返回写入的数据,并传给 P2 (可以按需缩减返回的内容)
-
P1 用搜索条件组装 key,将数据或者数据键写入 redis ;P2 读取 es 和 redis ,将两者的并集作为结果
-
P2 第一次未能搜到期望的数据时,等待一段时间后重试,直至搜到数据
-
如果 P1 和 P2 在同一个进程中执行,将数据缓存至进程内存中,不必使用 redis
缓存与索引
上一节中使用 redis 缓存来解决 es 延迟,在具体实施的过程中,我们可以选择缓存数据键,也可以选择缓存数据记录。如果仅仅缓存数据键,其实是将 redis 用作了非全文索引数据库。使用 NoSQL 技术时,我们将数据和索引拆分开来,分别使用不同的数据库存储它们。es 无法提供最近的数据搜索服务,那么我们可以寻找另一个可能的索引数据库。这种数据库仅需要存储最近的数据,并提供实时的搜索服务。
graph 数据库
关系模型中,实体之间通过主键和外键互相链接,一同构成了一张关系网。实际应用中,具有因果关系的非独立搜索场景,几乎都是关系查询。graph 数据库是处理这种任务的不二选择,使用 neo4j 来替换 redis 是值得考虑的。
未来的展望
redis 也好,neo4j 也好,它们所能提供的服务都是 es 的子集。倘若未来的某一天,有人开发出了一种基于内存的类 es 数据库,那么 NoSQL 的应用领域必将得到极大的扩充。