记一次引入Elasticsearch的系统架构实战

本文作者介绍了如何在面临海量数据挑战时引入Elasticsearch的实战经验,包括背景、Elasticsearch的优缺点、核心技术、与传统数据库的对比、服务器选型、需求场景选择和设计方案。通过详细分析,展示了如何处理用户阅读记录和作品搜索功能,以及数据同步、监控等方面,旨在为读者提供实用的系统架构参考。
摘要由CSDN通过智能技术生成

前言

我曾经面试安踏的技术岗,当时面试官问了我一个问题:如果你想使用某个新技术但是领导不愿意,你怎么办?

  对于该问题我相信大家就算没有面试被问到过,现实工作中同事之间的合作也会遇到。 

因此从我的角度重新去回答这个问题,有以下几点:

  1.师出有名,在软件工程里是针对问题场景提供解决方案的,如果脱离的实际问题(需求)去做技术选型,无疑是耍流氓。大家可以回顾身边的“架构师”、“技术Leader”是不是拍拍脑袋做决定,问他们为什么这么做,可能连个冠冕堂皇的理由都给不出。

  2.信任度,只有基于上面的条件,你才有理由建议引入新技术。领导愿不愿意引入新技术有很多原因:领导不了解这技术、领导偏保守、领导不是做技术的等。那么我认为这几种都是信任度,这种信任度分人和事,人就是引入技术的提出者,事就是提出引入的技术。

  3.尽人事,任何问题只是单纯解决都是简单的,以我以往的做法,把基本资料收集全并以通俗易懂的方式归纳与讲解,最好能提供一些能量化的数据,这样更加有说服力。知识普及OK后,就可以尝试写方案与做个Demo,方案最好可以提供多个,可以分短期收益与长期收益的。完成上面几点可以说已经尽人事了,如果领导还不答应那么的确有他的顾虑,就算无法落实,到目前为止的收获也不错。

  4.复杂的是人,任何人都无法时刻站在理智与客观的角度去看待问题,事是由人去办的,所以同一件事由不同的人说出来的效果也不一样。因此得学会向上管理、保持与同事之间合作融洽度,尽早的建立合作信任。本篇文章更多叙述的事,因此人方面不过多深究,有兴趣的我可以介绍一本书《知行 技术人的管理之路》。

  本篇我的实践做法与上述一样,除了4无法体现。那么下文我分了4大模块:业务背景介绍基础概念讲解方案的选用技术细节

  该篇文章不包含代码有8000多千字,花了我3天时间写,可能需要您花10分钟慢慢阅读,我承诺大家正文里面细节满满

  曾有朋友建议我拆开来写,但是我的习惯还是希望以一篇文章,这样更加系统化的展示给大家。当然大家有什么建议也可以在下方留言给我。

  部分源码,我放到了https://github.com/SkyChenSky/Sikiro 的Sikiro.ES.Api里

背景

  本公司多年以来用SQL Server作为主存储,随着多年的业务发展,已经到了数千万级的数据量。

  而部分非核心业务原本应该超亿的量级了,但是因为从物理表的设计优化上进行了数据压缩,导致维持在一个比较稳定的数量。压缩数据虽然能减少存储量,优化提供一定的性能,但是同时带来的损失了业务可扩展性。举个例子:我们平台某个用户拥有最后访问作品记录总的阅读时长,但是没有某个用户的阅读明细,那么这样的设计就会导致后续新增一个抽奖业务,需要在某个时间段内阅读了多长时间或者章节数量的作品,才能参加与抽奖;或者运营想通过阅读记录统计或者分析出,用户的爱好受欢迎的作品。现有的设计对以上两种业务情况都是无法满足的。

  此外我们平台还有作品搜索功能,like ‘%搜索%’查询是不走索引的而走全表扫描,一张表42W全表扫描,数据库服务器配置可以的情况下还是可以的,但是存在并发请求时候,资源消耗就特别厉害了,特别是在偶尔被爬虫爬取数据。(我们平台API的并发峰值能达到8w/s,每天的接口在淡季请求次数达到了1亿1千万)

  关系型数据库拥有ACID特性,能通过金融级的事务达成数据的一致性,然而它却没有横向扩展性,只要在海量数据场景下,单实例,无论怎么在关系型数据库做优化,都是只是治标。而NoSQL的出现很好的弥补了关系型数据库的短板,在马丁福勒所著的《NoSQL精粹》对NoSQL进行了分类:文档型、图形、列式,键值,从我的角度其实可以把搜索引擎纳入NoSQL范畴,因为它的确满足的NoSQL的4大特性:易扩展、大数据量高性能、灵活的数据模型、高可用。我看过一些同行的见解,把Elasticsearch归为文档型NoSQL,我个人是没有给他下过于明确的定义,这个上面说法大家见仁见智。

  MongoDB作为文档型数据库也属于我的技术选型范围,它的读写性能高且平衡、数据分片与横向扩展等都非常适合我们平台部分场景,最后我还是选择Elasticsearch。原因有三:

  1. 我们运维相比于MongoDB更熟悉Elasticsearch。
  2. 我们接下来有一些统计报表类的需求,Elastic Stack的各种工具能很好满足我们的需求。
  3. 我们目前着手处理的场景以非实时、纯读为主的业务,Elasticsearch近实时搜索已经能满足我们。

Elasticsearch优缺点

百度百科 :

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch由Java语言开发的,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。

  对于满足当下的业务需求和未来支持海量数据的搜索,我选择了Elasticsearch,其实原因主要以下几点:

优点 描述
横向可扩展性 可单机、可集群,横向扩展非常简单方便,自动整理数据分片
索引被分为多个分片(Shard),利用多台服务器,使用了分而治之的思想提升处理效率
支持搜索多样化 与传统关系型数据库相比,ES提供了全文检索、同义词处理、相关度排名、复杂数据分析、海量数据的近实时处理等功能
高可用 提供副本(Replica)机制,一个分片可以设置多个副本,假如某服务器宕机后,集群仍能正常工作。
开箱即用 简易的运维部署,提供基于Restful API,多种语言的SDK

  那么我个人认为Elasticsearch比较大的缺点只有 吃内存,具体原因可以看下文内存读取部分。

Elasticsearch为什么快?

我个人对于Elasticsearch快的原因主要总结三点:

  • 内存读取
  • 多种索引
    • 倒排索引  
    • doc values
  • 集群分片

内存读取

  Elasticsearch是基于Lucene, 而Lucene被设计为可以利用操作系统底层机制来缓存内存数据结构,换句话说Elasticsearch是依赖于操作系统底层的 Filesystem Cache,查询时,操作系统会将磁盘文件里的数据自动缓存到 Filesystem Cache 里面去,因此要求Elasticsearch性能足够高,那么就需要服务器的提供的足够内存给Filesystem Cache 覆盖存储的数据

  上一段最后一句话什么意思呢?假如:Elasticsearch 节点有 3 台服务器各64G内存,3台总内存就是 64 * 3 = 192G。每台机器给 Elasticsearch  jvm heap 是 32G,那么每服务器留给 Filesystem Cache 的就是 32G(50%),而集群里的 Filesystem Cache 的就是 32 * 3 = 96G 内存。此时,在 3 台Elasticsearch服务器共占用了 1T 的磁盘容量,那么每台机器的数据量约等于 341G,意味着每台服务器只有大概10分之1数据是缓存在内存的,其余都得走硬盘。

  说到这里大家未必会有一个直观得认识,因此我从《大型网站技术架构:核心原理与案例分析》第36页抠了一张表格下来:

操作 响应时间
打开一个网站 几秒
在数据库中查询一条记录(有索引) 十几毫秒
机械磁盘一次寻址定位 4毫秒
从机械磁盘顺序读取1MB数据 2毫秒
从SSD磁盘顺序读取1MB数据 0.3毫秒
从远程分布式缓存Redis读取一个数据 0.5毫秒
从内存中读取1MB数据 十几微秒
Java程序本地方法调用 几微秒
网络传输2KB数据 1微秒

   从上图加粗项看出,内存读取性能是机械磁盘的200倍,是SSD磁盘约等于30倍,假如读一次Elasticsearch走内存场景下耗时20毫秒,那么走机械硬盘就得4秒,走SSD磁盘可能约等于0.6秒。讲到这里我相信大家对是否走内存的性能差异有一个直观的认识。

对于Elasticsearch有很多种索引类型,但是我认为核心主要是倒排索引和doc values

倒排索引

  Lucene将写入索引的所有信息组织为倒排索引(inverted index)的结构形式。倒排索引是一种将分词映射到文档的数据结构,可以认为倒排索引是面向分词的而不是面向文档的。

  假设在测试环境的Elasticsearch存放了有以下三个文档:

  • Elasticsearch Server(文档1)
  • Masterring Elasticsearch(文档2)
  • Apache Solr 4 Cookbook(文档3)

  以上文档索引建好后,简略显示如下:

词项 数量 文档
4 1 <3>
Apache 1 <3>
Cooking 1 <3>
Elasticsearch 2 <1><2>
Mastering 1 <1>
Server 1 <1>
Solr 1 <3>

  如上表格所示,每个词项指向该词项所出现过的文档位置,这种索引结构允许快速、有效的搜索出数据。

doc values  

  对于分组、聚合、排序等某些功能来说,倒排索引的方式并不是最佳选择,这类功能操作的是文档而不是词项,这个时候就得把倒排索引逆转过来成正排索引,这么做会有两个缺点:

  1. 构建时间长
  2. 内存占用大,易OutOfMemory,且影响垃圾回收

  Lucene 4.0之后版本引入了doc values和额外的数据结构来解决上面

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值