【问题标题】:Speed a search cache without using too much memory在不使用太多内存的情况下加速搜索缓存
【发布时间】:2017-12-26 23:55:48
【问题描述】:

我必须访问一个包含 380,000 个条目的数据库。我没有对数据库的写访问权限,我只能读取它。我使用地图创建了一个搜索功能,可以按名字搜索用户。这是我的过程: 1 - 从数据库加载所有内容 2 - 将所有内容存储到Map<Charactere, ArrayList<User>>,根据用户名字的第一个字母使用字母来存储用户。

<A> {Alba, jessica, Alliah jane, etc ...}
<B> {Birsmben bani, etc ...}

当有人搜索用户时,我会使用输入的名字的第一个字母并使用map.get(firstletter),然后遍历 ArrayList 以查找所有用户。

地图 我猜想在内存中占用很大的空间(380,000 个用户对象)。我不得不增加堆大小 我想让它更快。使用名字作为地图的键,以使其更快(有很多人有相同的名字)。

我有两个解决方案:

1 - Still use a map with firstname as key (increasing the heap size again?)
2 - Use files on the disk instead of Map (Alba.dat will contain all Alba for example) and open the right file for each search. No need to incease the heap size, but are there any side effects?

哪个更好? (优点和缺点)

Update with more info

这是一个客户数据库,其中包含通过电话联系我们的客户服务的客户。接听电话的人必须使用客户姓名(通常是名字,然后是姓氏)进行搜索。使用 Db 搜索速度太慢。我实施的解决方案已经快了很多(1/2 秒 vs 26 秒使用 db),但我想改进它。

【问题讨论】:

  • 您是否假设一旦加载的数据将永远不会被其他人更改到数据库中?为什么需要缓存全部数据而不是最常用的数据?请解释问题域,很难理解为什么需要在内存中维护整个数据库的副本。如果是这样,您是否考虑过使用内存数据库?
  • 我每 5 分钟刷新一次缓存。这是一个客户群,我不知道哪些名字是最常搜索的。我不必维护数据库的完整副本,只需保留用户的副本(名字、姓氏、id、文档列表)
  • 该数据库中是否有任何最后修改的列?每 5 分钟获取 38 万条记录将非常昂贵。
  • 您需要如何搜索数据?换句话说,什么是关键,你在寻找什么?即你会搜索名字,姓氏,名字+姓氏的记录吗? id 是唯一键吗?如果你有 2 个名字和姓氏相同的用户,那么你会返回什么?
  • 我使用名字或名字、姓氏进行搜索。例如,“Jessica Alba”的搜索查询可以是“Alba, j*”或“Alb*, jess*”。我搜索特定用户以及与该客户相关的所有文档。客户通过他们的 id 来区分。他们是否有相同的名字/姓氏并不重要。我无权修改数据库。刷新缓存需要2秒。

标签: java caching arraylist hashmap


【解决方案1】:

恕我直言,我认为您不必将所有条目缓存在内存中,但其中一部分可能:

  • 也许只使用环形缓冲区,或者
  • 更复杂,更有意义的是,实现一个 LFU 缓存,它只保留 N 个最常访问的项目。有关如何实现此类缓存的提示,请参阅 this question

【讨论】:

  • 问题是我不知道哪些是最常用的名字。他们没有记录这类活动。
  • 基于运行时活动(“get”操作),LFU 算法将帮助您保留最常用的项目并驱逐那些不常用的项目。你不需要以某种方式识别它。
【解决方案2】:

您的方法存在几个问题:

  • 这意味着用户数量不会改变,一个好的应用程序设计可以在不改变软件的情况下与任意数量的用户一起工作
  • 这意味着当前问题是唯一的问题。如果下一个需要实现的需求是“按呼叫者 ID 搜索”或“按邮政编码搜索”,会发生什么?
  • 这是在重新发明轮子,您目前正在从头开始编写数据库、索引或信息检索解决方案(无论您想如何命名)

正确的做法是将用户数据导出到提供适当搜索功能的数据库引擎中。如果您有修改时间戳,或者如果您可以拦截更新并将其重新应用到您的搜索索引,则希望可以加快导出/提取速度。

您用于搜索的内容并不重要,现代系统上的简单数据库就足够快了。大多数还提供索引功能以加快搜索速度。如果您想要一些可以嵌入到您的应用程序中并且专门用于搜索并解决上述问题的东西,我建议您使用 Lucene。

【讨论】:

  • - 即使用户数改变也没关系,因为缓存每 5 分钟刷新一次(刷新大约需要 4 秒,使用镜像系统地图永远不会为空)/对于其他我使用的搜索类型已经使用数据库(通过电话号码或邮政编码)。问题是按名称搜索时速度很慢。其余的我不想重新发明轮子,只需写一些简单的东西来加快搜索速度。它已经很好了。我只想改进
猜你喜欢
  • 2018-05-08
  • 1970-01-01
  • 2011-09-05
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 2018-01-06
  • 2013-12-05
  • 1970-01-01
相关资源
最近更新 更多