现有系统架构
存在的问题
现有系统采用redis+mysql方案,对数据进行存储和统计。其中,redis统计当天数据总和并定时存入mysql;而原始数据是直接落库mysql,按月分表存储。
在查询统计数据时,因为按天统计好了,数据量小,故无性能瓶颈。而在查询历史数据时,因为需要查询整个月的数据,且查询条件多样,所有会有性能瓶颈,接口耗时多。
核心痛点:数据量大,搜索条件多,查询慢
解决的方法
- 降低单表数量
- 采用分库分表
- 增加索引、让查询命中索引,提高查询效率
前两种办法类似,都是通过降低单表数据量,来提高查询速度。分库缺点不用多说,无法做关联查询,且对技术要求较高。而分表,受业务需要,也不好在拆分,目前只按月分表。最后就是第三种方案,增加索引。通过新增组合索引是能解决大部分问题,但也会引入新的问题。
首先,如果查询条件过多(比如五六个查询条件,且每个条件可选可不选),则会导致新建组合索引过多。我们都知道,索引过多会导致索引文件过大,占用过多磁盘空间,且会影响写入性能。
其次,有时需要多表联查,这种情况下,即使添加索引,查询效率也不会很好。当然,为了减少关联查询,我们可以对单表做字段冗余。但这并不是很好的解决方案。
总结:能解决问题,也会引入新的问题
引入es原因
核心功能
es的定位就是用来做海量数据的全文检索,这也是其核心功能。所以针对现有系统中的数据量大,查询条件多的问题,能很好的适配解决。另外,除检索外,也能像mysql一样,做各种统计聚合。
特点
- 速度快,千万级数据毫秒级查询
- 不需要像mysql一样自己维护索引,es自动帮忙维护
- 集群部署简单,支持高可用、易扩容
- 自动实现冗余备份、负载均衡
用一句话来总结,就是:把你能遇到的问题都给解决,把需要手动参与的都给你自动实现
使用场景
- 日志采集
- 海量数据检索,百度搜索这种
es基本介绍
基础概念
- index
索引index,其实就是相同结构的数据集合。可类比mysql数据表的概念 - type
es7之前版本有type概念,之后版本已经取消。很多人将type类比mysql数据表的概念,虽然形式上很符合,也好理解。但其实是不对的,因为底层的实现是完全不同的,这种类比很容易误导人,官方也曾批评过这种解释 - doc
doc就是一条文档,一条数据记录。可类比mysql中的行数据。不过在es中,文档是以json格式组成的,而mysql是字段形式,是行数据。 - map
是文档doc的数据结构,包含哪些字段、字段类型是什么、分片数量等待。可类比mysql表结构DDL信息。 - shard
指数据分片,在es中,为了做到高性能,数据会进行分片,类似于mysql中的分表。同时为了高可用,es引入了副本的概念,即每个主分片都会有若干副本。当主分片挂了后,副本仍能对外提供数据。 - lucence、segment、translog、refresh、flush、cluster、node、corsponding-node
这一类概念涉及到底层实现,暂不过多解释,后面会有专门介绍。
对比mysql
es | mysql |
---|---|
index | table |
doc | row |
map | schema ddl |
shard | 分表或分区 |
全文索引 | 唯一索引、组合索引、主键等 |
底层实现:倒排索引 | 底层实现:b/b+tree |
常用数据类型
分类 | 数据类型 |
---|---|
文本 | text、keyword |
非文本 | long、float |
日期 | date |
其他 | nested等 |
注意:
- text会分词,即字段内容会被分词,然后存入倒排索引中。
- keyword不会分词。text和keyword在查询时候的区别,后文会专门举例说明。
- 日期类型虽然是date,但底层还是作为long型存储。