带你读《2022技术人的百宝黑皮书》——数据库存储选型经验总结(2)https://developer.aliyun.com/article/1340015?groupCode=taobaotech
搜索型 NoSql(代表 —-ElasticSearch)
传统关系型数据库主要通过索引来达到快速查询的目的,但是在全文搜索的场景下,索引是无能为力的,like 查询一来无法满足所有模糊匹配需求,二来使用限制太大且使用不当容易造成慢查询,搜索型 NoSql 的诞生正是为了解决关系型数据库全文搜索能力较弱的问题,ElasticSearch 是搜索型 NoSql 的代表产品。
全文搜索的原理是倒排索引,我们看一下什么是倒排索引。要说倒排索引我们先看下什么是正排索引,传统的正排索引是文档 –> 关键字的映射,例如”Tom is my friend” 这句话,会将其切分为”Tom”、”is”、” my”、”friend” 四个单词,在搜索的时候对文档进行扫描,符合条件的查出来。这种方式原理非常简单,但是由于其检索效率太低,基本没什么实用价值。
倒排索引则完全相反,它是关键字 –> 文档的映射,举例来说,现在这里有四个短句:
- "Tom is Tom"
- "Tom is my friend"
- "Thank you, Betty"
- "Tom is Betty's husband"
搜索引擎会根据一定的分词规则将一句话切成 N 个关键字,并以关键字的维度维护关键字在每个文本中的出现次数。这样下次搜索”Tom” 的时候,由于 Tom 这个词语在”Tom is Tom”、”Tom is my friend”、”Tom is Betty’s husband” 三句话中都有出现,因此这三条记录都会被检索出来,且由于”Tom is Tom” 这句话中” Tom” 出现了 2 次,因此这条记录对”Tom” 这个单词的匹配度最高,最先展示。这就是搜索引擎倒排索引的基本原理,假设某个关键字在某个文档中出现,那么倒排索引中有两部分内容:
- 文档ID
- 在该文档中出现的位置情况
可以举一反三,我们搜索”Betty Tom” 这两个词语也是一样,搜索引擎将”Betty Tom” 切分为”Tom”、” Betty” 两个单词,根据开发者指定的满足率,比如满足率 = 50%,那么只要记录中出现了两个单词之一的记录都会被检索出来,再按照匹配度进行展示。
搜索型 NoSql 以 ElasticSearch 为例,它的优点为:
- 支持分词场景、全文搜索,这是区别于关系型数据库最大特点
- 支持条件查询,支持聚合操作,类似关系型数据库的Group By,但是功能更加强大,适合做数据分析
- 数据写文件无丢失风险,在集群环境下可以方便横向扩展,可承载PB级别的数据
- 高可用,自动发现新的或者失败的节点,重组和重新平衡数据,确保数据是安全和可访问的
同样,ElasticSearch 也有比较明显的缺点:
- 性能全靠内存来顶,也是使用的时候最需要注意的点,非常吃硬件资源、吃内存,大数据量下64G + SSD基本是标配,相同的配置多一倍内存,一个月差不多就要多花好多钱。至于ElasticSearch内存主要用在以下几个地方:
- Indexing Buffer ElasticSearch基于Luence,Lucene的倒排索引是先在内存里生成,然后定期以
Segment File的方式刷磁盘的,每个Segment File实际就是一个完整的倒排索引
- Segment Memory 倒排索引前面说过是基于关键字的,Lucene在4.0后会将所有关键字以FST这种数
据结构的方式将所有关键字在启动的时候全量加载到内存,加快查询速度,官方建议至少留系统一半内存给Lucene
- 各类缓存----Filter Cache、Field Cache、Indexing Cache等,用于提升查询分析性能,例如Filter Cache用于缓存使用过的Filter的结果集
- Cluter State Buffer ElasticSearch被设计为每个Node都可以响应用户请求,因此每个Node的内存中
都包含有一份集群状态的拷贝,一个规模很大的集群这个状态信息可能会非常大
- 读写之间有延迟,写入的数据差不多1s样子会被读取到(数据写入时需要维护很多索引)
- 数据结构灵活性不高,字段一旦建立就没法修改类型了,假如建立的数据表某个字段没有加全文索引,想加上, 那么只能把整个表删了再重建。
因此,搜索型 NoSql 最适用的场景就是有条件搜索尤其是全文搜索的场景,作为关系型数据库的一种替代方案,通常搜索型 NoSql 也会作为一层前置缓存,来对关系型数据库进行保护。
另外,搜索型数据库还有一种特别重要的应用场景。我们可以想,一旦对数据库做了分库分表后,原来可以在单表中做的聚合操作、统计操作是否统统失效?例如我把订单表分 16 个库,1024 张表,那么订单数据就散落在 1024 张表中,我想要统计昨天浙江省单笔成交金额最高的订单是哪笔如何做?我想要把昨天的所有订单按照时间排序分页展示如何做?这就是搜索型 NoSql 的另一大作用了,我们可以把分表之后的数据统一打在搜索型 NoSql 中,利用搜索型 NoSql 的搜索与聚合能力完成对全量数据的查询。
带你读《2022技术人的百宝黑皮书》——数据库存储选型经验总结(4)https://developer.aliyun.com/article/1340013?groupCode=taobaotech