搜索:ElasticSearch vs 关系型数据库
前言
我们开发应用时,本质上都是对数据的增删查改,现在我们来说一下查,一般web应用中的查都是预先定义的,会在搜索部分预先定义好搜索字段,因为基于传统关系型数据库,我们都是预先进行各方面的考虑然后来预先定义好SQL语句的,这种查询与其说是查询数据不如说是在过滤数据。
1. 先来看看传统数据库对搜索的支持。
就拿当下最流行的MySQL为例,MySQL是当下Web应用开发中最流行的关系型数据库。对此数据库了解的人很多,做项目时技术储备上不会有什么问题。包括调优等技巧,懂的人也不少。
拿电商业务来说,假设用MySQL来做搜索会遇到什么问题呢,假如一个用户要搜索某个商品,那传统搜索会做成预先设定一些搜索字段,首先对用户来说非常繁琐不方便,用户需要的是键入关键字搜索到自己需要的商品,这一点关系型数据库做不到,其次,比如用户在商品描述里键入“省电的取暖器”,如果用MySQL实现会写如下语句:SELECT * FROM goods where description like %关键词%,这样做理论上确实能匹配到一些数据,但假设商品描述里并不是这么写的,而是写成“取暖器省电”,那就匹配不到了。另外从技术上说like是全表扫描的,如果表数据量少还好说要是数据量千万级别甚至更多,那耗时是不可想象的,用户体验会非常糟糕。另外对于搜索中的分词问题更是传统关系型数据库所做不到的。
2. 再来看ElasticSearch
ElasticSearch是一个基于Lucene的分布式搜索引擎,业内简称ES。它提供了基于RESTful 风格的全文搜索API。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前最流行的企业级搜索引擎。另外,它的分布式设计让它天生就适合用于云计算中,并能够达到准实时搜索,而且安装使用方便,还拥有稳定,可靠,快速等特性,是当下搜索技术中不二的选择。
但是ElasticSearch不支持事务,不适合做基础数据存储,加入选择ES做数据存储,则免不了出现脏数据。所以推荐使用MySQL作为数据存储,利用事务特性,可以做稳定存储。再利用ES的搜索功能来实现应用的搜索功能。
3. 如何让数据库和ES结合使用
创建的每个Elasticsearch索引都应该由符合ACID的数据存储支持。 数据库应该是基础数据来源并导入ES索引。 如果异常情况发生(节点丢失,中断或误操作 )导致丢失了索引,您将能够完全恢复它。 一般的用法是另外的数据库比如MySQL里面有一份,然后实时同步到ES,这样一个用于键值查询,一个用于各种其他查询。 如果ES升级了之类的,比如数据结构变了,那么老版本数据可以不要,直接MySQL再导入一份到新版本,还可以恢复。 logstash的同步插件如logstash_input_jdbc 不支持同步删除操作,建议改为更新操作加标记flag,或者通过业务逻辑实现同步删除操作。
核心操作:
ES中只存储检索字段,利于快速检索、全文检索。 MySQL中存储全部字段,利用ACID事务特性保证数据准确性。 通过关联字段建立关联,比如:productId在ES和mysql中要有相同的值。 核心数据先通过ES快速获取Id(如product_id),再通过MySQL查询出详细数据。
引申讨论:如何做关系型数据库和ES之间的数据同步。