分布式SQL查询引擎Presto原理介绍

前言

我们实时引擎组新引入了一款分布式SQL查询引擎,名字叫Presto,目前已经调研和测试了2个月了,并且期间某平台也从impala平台迁入到了Presto平台,查询性能有了2-3倍的提升(各种原因导致),所以本文将结合作者这段时间的测试和调研研究,来揭开Presto的神秘面纱。

Presto是神马

Presto是由Facebook开发的一个分布式SQL查询引擎, 它被设计为用来专门进行高速、实时的数据分析。它的产生是为了解决Hive的MapReduce模型太慢以及不能通过BI或Dashboards直接展现HDFS数据等问题。Presto是一个纯粹的计算引擎,它不存储数据,其通过Connector获取第三方Storage服务的数据。

历史

  • 2012年秋季,Facebook启动Presto项目
  • 2013年冬季,Presto开源
  • 2017年11月,11888 commits,203 releases,198 contributors

功能和优点

  • Ad-hoc,期望查询时间秒级或几分钟
  • 比Hive快10倍
  • 支持多数据源,如Hive、Kafka、MySQL、MonogoDB、Redis、JMX等,也可自己实现Connector
  • Client Protocol: HTTP+JSON, support various languages(Python, Ruby, PHP, Node.js Java)
  • 支持JDBC/ODBC连接
  • ANSI SQL,支持窗口函数,join,聚合,复杂查询等

架构

  • Master-Slave架构
  • 三个模块
  • Coordinator、Discovery Service、Worker
  • Connector

Read More

说说常见搜索引擎的分布式解决方法

随着索引数据的增大以及请求的增多,分布式搜索是最好的一种解决方案,主要解决两个问题,其一是能让单台机器load所有索引数据到内存中,其二是请求延时大,解决请求latency问题。我之前为团队写了篇专利,内容是关于分布式搜索解决方案的,所以粗略的看了下大部分开源的搜索引擎是怎么实现分布式的,后面的文章我会简单说下常见的搜索引擎的分布式解决方案。

首先我们先说下几个简单概念,分布式搜索都是M*N(横向切分数据,纵向切分流量)这个维度去解决问题的,虽然不同产品或场景概念不完全相同,读者可以简单认为一份完整的数据,被均分为M份,每一份被称为一个分配(Shard或者Partition),然后提供对每个Shard提供N份副本(Replica)。那么分布式的设计就围绕着以下问题:

  • 如何选择合适的分片(Shard),副本(Replica)的数量
  • 如何做路由,即怎么在所有Shard里找到一份完整的数据(找到对应的机器列表)
  • 如何做负载均衡
  • 如果提高服务的可扩展性
  • 如何提高服务的服务能力(QPS),当索引和搜索并发量增大时,如何平滑解决
  • 如何更新索引,全量和增量索引的更新解决方法
  • 如果提高服务的稳定性,单台服务挂掉怎么不影响整体服务等等

下面就说下常见的搜索引擎的分布式解决方案,因为开源的搜索产品基本上都没有在工作中用过,对代码细节并不是太了解,只是研究了下其原理,所以理解的会有些偏差,看官们如果发现错误直接指出即可。

Read More

Minder:一个分布式启停进程服务

关于

打算造个轮子,先备份下简单的设计手册吧。Minder是一个分布式启停进程服务,主要用于以下目的。

  • 命令或远程RPC调用启动和停止进程
  • 当进程挂掉,可以拉起来进程
  • 获得机器对应的系统信息,如CPU,内存,硬盘等等

设计

方案一(不采用)

分为Server和Client端

Server

Server在每台机器上都需要安装,Server是个常驻进程,负责真正的启停进程,同时需要一个Check线程,用于判断进程状态,当程序挂掉以便重启进程,重启进程可以在配置里有个次数限制。

Read More

一些常见的搜索查询树优化方法

搜索引擎服务收到一个Query后,一般引擎这边是这么搞得,解析语法,生成后缀表达式,即查询搜索树(Search Tree)。搜索查询树负责求交、求并和过滤。所以这个地方也是性能关键点。所以在解析语法后,一般要做查询搜索树优化,减少求交,求并和过滤操作的次数,以此来提高搜索服务的QPS和查询Latency。

因为同事在负责新实时索引的性能优化,我正好负责将全量索引格式迁移到新实时索引上面,即实时索引的代码即支持全量索引也支持实时索引,减少运维和代码维护成本。我在查阅代码的同事,顺便与同事沟通了一些优化方法,进入全量索引代码里发现老的全量索引里已经有一些优化方法了,这些方法应该是市面上常见的方法,多数人也是应该知道的,这里记录下吧。主流优化操作主要包括以下四种:

全AND操作

如果父子节点都是AND,则可以合并,如(A & B)& (C & D),优化后为 A & B & C & D ,能提早发现交为空,并退出,如下图所示。

Read More

dlog:高性能线程安全的C++日志库

打算闲暇时光写点靠谱的东西比如名字服务、KV存储等基础服务类软件,所以周末就先从封装一些基础库开始。上周末写了个C++日志库,支持多线程,性能也还不错,今天就做了下测试和修改了下bug。这里说下该库的使用方法,以及实现思路以及一些性能调优方法。欢迎交流和指教。

源码地址

https://github.com/armsword/dlog

编译

执行build.sh,在上层目录里会生成build文件,测试的可执行文件在release/bin目录下。

Read More

Earlybird:Twitter实时搜索引擎

简单说下,2011年左右的Paper,Paper里说Twitter的实时索引和检索系统叫做Earlybird,Paper中主要讲了2件事,第一个就是支持Twitter的实时索引的倒排索引结构是怎么样的,第二个就是利用Java并发模型,处理并发读写。

该引擎功能

  • 低延时、高吞吐能力;
  • 能处理突发峰值(Weibo的特性);
  • 突出时效性,时间越近,排名应该越靠前;
  • 该实时引擎支持AND、OR、NOT以及短语查询,实时性大约10S,查询latency 50ms;

该实时引擎,基于Lucene,使用Java开发,理由是

  • 利用已存在的Lucene代码,并用来做全量索引;
  • 适用于Twitter以JVM为中心的开发环境;
  • 利用Java和JVM提供容易理解的并发模型;

其实上面几条理由与阿里很多开发项目类似,但是阿里的搜索引擎是C++编写的,质量也是非常不错的,叫问天(HA3)。

Read More

记一次线上Bug的查找过程和思路

前言

简单说下问题情况,Proxy即作为客户端又有服务端功能,其接受QS(Query Server)的请求,之后向BS(索引服务)发送请求,然后根据BS的返回结果Merge后返回给QS。不能泄露太多东西,所以本文主要是整理一些知识点和问题查找思路。

问题和现象

  • Proxy机器上出现大量的CLOSE_WAIT。
  • Proxy失去服务能力,内存使用不为0,CPU使用率为0。
  • 机器报警,TcpListenOverFlows。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
命令查看:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'


结果:
TIME_WAIT 31927
CLOSE_WAIT 1570
ESTABLISHED 40

TIME_WAIT:表示主动关闭,通过优化系统内核参数可容易解决。
CLOSE_WAIT:表示被动关闭,需要从程序本身出发。
ESTABLISHED:表示正在通信


注:以上数据非真实线上情况,只为举例

Read More