File tree Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Original file line number Diff line number Diff line change 84
84
考虑到数据量每天可能会增长,同时也会删除一些不再被搜索的词条。如果假设每天有2%的新增查询,并且我们维护过去一年的索引,预计的总存储需求为:
85
85
86
86
** 3 GB + (0.02 × 3 GB × 365 天) = 25 GB**
87
+
88
+ ## 6. 数据分区
89
+ 尽管我们的索引可以轻松地适配到单个服务器上,但为了实现更高的效率和更低的延迟,仍可以对其进行分区。如何有效地对数据进行分区以将其分布到多个服务器上?
90
+
91
+ ### a. 基于范围的分区
92
+ 假设我们根据短语的首字母将其存储在不同的分区中,例如,将所有以字母“A”开头的术语存储在一个分区中,以“B”开头的存储在另一个分区中,以此类推。对于出现频率较低的字母,还可以将它们合并到一个数据库分区中。
93
+ 这种分区方案需要在静态情况下设计,以确保数据的存储和查询始终具有可预测性。
94
+ 此方法的主要问题是可能导致服务器负载不平衡。例如,如果我们将所有以字母“E”开头的术语存储在一个分区中,但后来发现“E”开头的术语数量过多,以至于无法容纳在一个数据库分区中。
95
+ 上述问题几乎会出现在所有静态定义的分区方案中,因为无法在静态情况下预测每个分区是否能够适配到单个服务器。
96
+
97
+ ### b. 基于服务器最大容量的分区
98
+ 假设我们根据服务器的最大内存容量对trie结构进行分区。只要服务器内存充足,我们可以将数据存储在该服务器中。当某个子树无法适配当前服务器时,就在此处断开分区,将范围分配给当前服务器,然后转到下一个服务器继续这个过程。例如:
99
+ - 第一台服务器存储从“A”到“AABC”的所有术语;
100
+ - 第二台服务器存储从“AABD”到“BXA”的术语;
101
+ - 第三台服务器存储从“BXB”到“CDA”的术语。
102
+
103
+ 我们可以通过哈希表快速访问这一分区方案:
104
+ - 服务器1:A-AABC
105
+ - 服务器2:AABD-BXA
106
+ - 服务器3:BXB-CDA
107
+
108
+ ** 查询场景** :
109
+ - 如果用户输入“A”,需要同时查询服务器1和服务器2以找到推荐结果;
110
+ - 如果用户输入“AA”,仍需查询服务器1和服务器2;
111
+ - 当用户输入“AAA”时,只需查询服务器1即可。
112
+
113
+ 可以在trie服务器前设置一个负载均衡器,存储分区映射并将流量重定向到相应的服务器。如果需要从多个服务器查询数据,可以选择在服务器端合并结果,或者让客户端处理合并。如果在服务器端处理合并,则需要在负载均衡器和trie服务器之间添加一个聚合层(称为“聚合服务器”),这些服务器负责从多个trie服务器中聚合结果并返回给客户端。
114
+ ** 缺点** :即使基于最大容量分区,仍可能导致热点问题,例如,对于大量以“cap”开头的查询,请求集中到某一台服务器时会造成高负载。
115
+
116
+ ### c. 基于术语哈希的分区
117
+ 将每个术语传递给一个哈希函数,由该函数生成服务器编号,然后将术语存储在对应的服务器上。这种方法会使术语分布随机化,从而最大限度地减少热点问题。
118
+ ** 查询过程** :为获取某个术语的联想推荐,需要访问所有服务器并聚合结果。
119
+
You can’t perform that action at this time.
0 commit comments