在一个允许客户通过低代码/无代码工具自行配置的 SaaS 平台中,很难提前准确知道用户希望搜索哪些数据。一个客户会添加自己的字段和表单,另一个客户会配置自定义业务流程,第三个客户则会把找到的数据用于筛选、批量编辑或营销活动。
Kiva Teknoloji 面临的正是这一挑战。这家土耳其公司自 2009 年以来一直在开发云端商业应用。其主要产品 KivaCRM 构建在公司自研的 Kiva Cloud Platform 之上,将 CRM 与业务流程自动化、报表和分析工具结合在一起。客户可以自行配置表单、列表、流程、报表和仪表板,因此同一个平台被 40 多个行业的公司使用。
这种灵活性会直接影响搜索。每个 Kiva 客户都有自己的数据库,并且表结构会随着他们围绕自身流程配置应用而变化。这意味着搜索无法只针对一组固定字段配置一次后就保持不变。
在这里,Manticore Search 作为独立的搜索层与 MySQL 并行工作。它负责全文搜索,而 MySQL 仍然是主数据库。这种方式让 Kiva 降低了主数据库服务器的负载,增加了更灵活的搜索能力,同时几乎没有增加基础设施成本。
搜索是平台的一部分,而不只是一个搜索框
Kiva 会索引客户在应用中创建的各种数据。搜索可用于产品的不同部分,而且找到的记录不只是用来查看。
据 Kiva Teknoloji 首席工程师 Arda Beyazoglu 介绍,搜索用于分析、筛选、批量编辑记录、电子邮件和短信营销活动以及其他任务。
"我们使用 Manticore 进行全文搜索,并索引客户生成的各种数据。"
这不是那种使用预定义 schema 的典型目录搜索。每个 Kiva 客户都有独立的数据库,其结构取决于应用的配置方式。随着客户进行自定义,新的字段和实体会不断出现。
因此,搜索层必须适应每个客户的数据,而不是适配单一的预定义模型。
为什么 MySQL 全文搜索还不够
在迁移到 Manticore 之前,Kiva 使用的是 MySQL 内置的全文搜索。
据 Arda 介绍,它比 Manticore 更慢,并且会消耗主数据库服务器上的资源。这在 SaaS 环境中很重要:应用本身也需要同样的 CPU 和内存,因此搜索会开始与主要工作负载争抢资源。
因此,Kiva 将全文搜索 迁移到了独立层,而不是让 MySQL 同时处理主应用工作负载和搜索。
MySQL 仍然作为主数据存储,而 Manticore 接管了搜索。
为什么 Kiva 迁移到 Manticore
在使用 Manticore 之前,团队曾使用过一段时间的 Sphinx。后来,由于版本兼容性问题以及原有解决方案开发节奏较慢,Kiva 迁移到了 Manticore。团队仍然能够保留现有的搜索架构。
为每个客户使用独立的搜索表
现在的架构如下:
customer MySQL → search cache → periodically rebuilt table + RT table → Manticore distributed table → search → record IDs → MySQL
对于每个包含客户数据的表,Kiva 都会生成一个搜索缓存。然后,它会为每个客户创建一个独立的 Manticore distributed table 。
它组合了两个本地表:
- 一个每周完整重建一次;
- 实时变更写入 RT table 。
这样,用户可以搜索最新数据,而 Kiva 不必持续重建整个搜索表。
当用户在应用中搜索时,Manticore 会找到匹配的记录。随后,应用会在源 MySQL 表中执行点查找,以获取其余数据。
这样可以避免在 Manticore 中复制源表的完整内容。搜索只需要返回匹配记录的 ID,而应用则从 MySQL 中取回其余数据。
因此,每个系统都有清晰的职责:
- MySQL 存储应用的源数据;
- Manticore 负责搜索;
- 应用使用 ID 将搜索结果关联回源记录。
不需要专用搜索服务器
Kiva 客户之间的数据量差异很大:这个平台既服务小型企业,也服务大型企业。
Arda 给出了以下大致数字:
| 指标 | 数值 |
|---|---|
| 大多数表的大小 | 最高几 GB |
| 少数大型表 | 30 GB 及以上 |
| 较小表的完整重建 | 最多几分钟 |
| 较大表的完整重建 | 约 30–60 分钟 |
| Manticore 专用服务器 | Kiva 未使用 |
最后一点尤其值得注意。
Kiva 不会为 Manticore 配置专用服务器。这个搜索引擎会运行在应用服务器上,或运行在托管数据库副本的服务器上。
"我们从不在单独的服务器上运行 Manticore。它在空闲时占用的资源很少,并且 CPU 效率很高,所以在我们的规模下,额外的基础设施成本几乎为零。"
对 Kiva 来说,这意味着增加一个独立搜索层并没有变成另一个需要付费和维护的集群。
减轻 MySQL 负载,为应用释放更多资源
对 Kiva 来说,主要收益不只是全文搜索变得更快。
将搜索工作负载从 MySQL 中移出后,数据库服务器上的资源被释放出来。这些资源可以用于更重要的应用数据和操作,同时同一套基础设施现在也可以服务更多客户。
Manticore 还为 Kiva 带来了之前没有的能力,包括更高级的搜索方法和对更多语言的支持。
下一步:混合搜索
Kiva 也在考虑将 Manticore 用于带有 AI 功能的新应用。
据 Arda 介绍,团队正在考虑混合搜索 ,也就是结合全文搜索和向量搜索。对 Kiva 来说,这是现有架构的自然延伸:Manticore 已经作为客户数据的搜索层,因此可以在这里添加新的搜索方法,而无需将源数据从 MySQL 中移出。
目前,这还只是计划,并不是已经在生产环境中运行的功能。但它展示了搜索层如何从全文搜索演进为同时考虑查询中的词语及其含义的搜索。
搜索结构不断变化的数据
在 Kiva,Manticore 融入了现有基础设施,并不需要单独的搜索集群。
每个客户都有自己的数据库,并且 schema 会随着应用配置而变化。Manticore 将定期重建的表与 RT 表中的变更结合起来,并返回匹配记录的 ID。MySQL 仍然是主数据存储。
因此,Kiva 将全文搜索工作负载从主数据库中移出,更高效地利用了现有服务器,并将搜索变成了一项共享的平台能力——即使无法提前知道下一个客户会创建哪些字段和实体。

