1. 系统概述
The Elastic Stack,包括Elasticsearch、Kibana、Beats和Logstash(也成为ELK Stack)
Elasticsearch:简称ES,是一个开源的高扩展的分布式全文搜索引擎,是整个Elastic Stack技术栈的核心。它可以近乎实时地存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级的数据。
Kibana:是一个免费且开放的用户界面,能够让你对Elasticsearch数据进行可视化,并让您在Elastic Stack中进行导航。您可以进行各种操作,从跟踪查询负载,到理解请求如何流经您的整个应用,都能轻松完成。
Beats:是一款采集系统监控数据的代理agent,是在被监控服务器上以客户端形式运行的数据收集器的统称,可以直接把数据发送给Elasticsearch或者通过Logstash发送给Elasticsearch,然后进行后续的数据分析活动。
Logstash:服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到合适的存储库中
1.1 索引和分片
分片是 Elasticsearch 在集群中分发数据的关键。
把分片想象成数据的容器。文档存储在分片中,然后分片分配到集群中的节点上。当集群扩容或缩小,Elasticsearch 将会自动在节点间迁移分片,以使集群保持平衡。
一个分片(shard)是一个最小级别“工作单元(worker unit)”,它只是保存了索引中所有数据的一部分。
这类似于 MySql 的分库分表,只不过 Mysql 分库分表需要借助第三方组件而 ES 内部自身实现了此功能。
分片可以是主分片(primary shard)或者是复制分片(replica shard)。
在集群中唯一一个空节点上创建一个叫做 blogs 的索引。默认情况下,一个索引被分配 5 个主分片,下面只分配 3 个主分片和一个复制分片(每个主分片都有一个复制分片):
1.1.1 主分片
在一个多分片的索引中写入数据时,通过路由来确定具体写入哪一个分片中,大致路由过程如下:
shard = hash(routing) % number_of_primary_shards
routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到余数 。这个在 0 到 number_of_primary_shards 之间的余数,就是所寻求的文档所在分片的位置。
这解释了为什么要在创建索引的时候就确定好主分片的数量并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了。
索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据(实际的数量取决于数据、硬件和应用场景)。
1.1.2 复制分片
复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的 shard 取回文档。
每个主分片都有一个或多个副本分片,当主分片异常时,副本可以提供数据的查询等操作。主分片和对应的副本分片是不会在同一个节点上的,所以副本分片数的最大值是 n -1(其中 n 为节点数)。
当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整,根据需求扩大或者缩小规模。如把复制分片的数量从原来的 1 增加到 2 :
curl -H "Content-Type: application/json" -XPUT localhost:9200/blogs/_settings -d '
{
"number_of_replicas": 2
}'
分片本身就是一个完整的搜索引擎,它可以使用单一节点的所有资源。主分片或者复制分片都可以处理读请求——搜索或文档检索,所以数据的冗余越多,能处理的搜索吞吐量就越大。
对文档的新建、索引和删除请求都是写操作,必须在主分片上面完成之后才能被复制到相关的副本分片,ES为了提高写入的能力这个过程是并发写的,同时为了解决并发写的过程中数据冲突的问题,ES 通过乐观锁的方式控制,每个文档都有一个_version(版本)号,当文档被修改时版本号递增。一旦所有的副本分片都报告写成功才会向协调节点报告成功,协调节点向客户端报告成功。
1.2 分片的存储
ES集群中每个节点通过路由都知道集群中的文档的存放位置,所以每个节点都有处理读写请求的能力。
在一个写请求被发送到某个节点后,该节点即为协调节点,协调节点会根据路由公式计算出需要写到哪个分片上,再将请求转发到该分片的主分片节点上。假设shard=hash(routing)%4=0,则过程大致如下:
- 客户端向ES1节点(协调节点)发送写请求,通过路由计算公式得到值为0,则当前数据应被写到主分片S0上。
- ES1节点将请求转发到S0主分片所在的节点ES3,ES3接受请求并写入到磁盘。
- 并发将数据复制到两个副本分片R0上,其中通过乐观并发控制数据的冲突。一旦所有的副本分片都报告成功,则节点ES3将向协调节点报告成功,协调节点向客户端报告成功。
2. 环境搭建
2.1 环境初始化
- 准备三台服务器,配置及角色如下:
IP地址 | 主机名 | CPU | 内存 | 磁盘 | 角色 |
---|---|---|---|---|---|
192.168.19.101 | host1.test.com | 2 core | 4G | 20G+ | ES node |
192.168.19.102 | host2.test.com | 2 core | 4G | 20G+ | ES node |
192.168.19.103 | host3.test.com | 2 core | 4G | 20G+ | ES node |
- 基础设置
配置IP地址、主机名、hosts等,并设置免密登陆
- 关闭Selinux,防火墙(也可以不用关,后面添加规则)
[root@host1 ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
[root@host1 ~]# setenforce 0
[root@host2 ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
[root@host2 ~]# setenforce 0
[root@host3 ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
[root@host3 ~]# setenforce 0
- 安装同步工具,并编写同步脚本
[root@host1 ~]# yum install rsync -y
[root@host2 ~]# yum install rsync -y
[root@host3 ~]# yum install rsync -y
[root@host1 ~]# vim /usr/local/sbin/data_rsync.sh
#!/bin/bash
if [ $# -ne 1 ];then
echo "Usage: $0 /path/file"
exit
fi
if [ ! -e $1 ];then
echo "[ $1 ] dir or file not find!"
exit
fi
# 获取父路径
fullpath=`dirname $1`
# 获取子路径
basename=`basename $1`
# 进入父路径
cd $fullpath
for ((host_id=2;host_id<=3;host_id++))
do
# 使终端输出变为绿色
tput setaf 2
echo ===== rsyncing host${host_id}.test.com: $basename