构建ElasticSearch集群之前

摘自designing the perfect elasticsearch cluster 本文包含了设计elasticsearch cluster需要了解的方方面面,本文不会告诉你如何设计一个完美的es集群。 elasticsearch是一个搜索引擎,不是数据库,不会替代mysql elasticsearch是一个弹性搜索引擎,弹性体现在水平扩展、索引分片;elastic将索引拆分成多个分片存储在不同的host上,分片数量默认为5,需要根据实际workload调整以达到最优性能 高可用设计 elasticsearch集群包含一下4种节点类型: master nodes: 主节点 data node: 数据节点 http node: 查询节点 coordinating node: 协作节点 最小高可用集群设计: 1. 3数据中心 2. 3主节点,奇数个主节点防止脑裂,将3个主机点分散在各个数据中心 3. 2查询节点,在主节点数据中心各一个 4. 任意数量的数据节点 ES的分片分配算法允许分片分配在不同区域内,根据rack配置将主分片、备份分片分配在不同的区域中 cluster.routing.allocation.awareness.attributes: "rack_id" node.attr.rack_id: "dontsmokecrack" 理解luence: elasticsearch使用了luence库 1. 每个elasticsearch分片是一个luence索引,一个luence索引最大可包含2,147,483,519条记录。 2. luence将索引划分为多个段,luence顺序搜索这些段;当新写请求来时会创建段,写提交或关闭时, 段即不可变,有新记录添加到elasticsearch index时,luence会创建新的段,luence会不断的将小的段 合并成大的段。luence搜索段是串行的,所以段越多延迟越大。当luence合并时会占用CPU与I/O进而降 低index速度。 3. 当更新或删除文档时luence执行copy on write操作,删除只将文档标记为已删除,索引磁盘占用会 一直增长,除非整个索引删除。 4. luence执行merge时,会将两个段合并成一个新的段后再删除旧的段,merge要确保磁盘空间足够 硬件 CPU: 复杂查询 ElasticSearch主要通过thread_pools使用CPU资源,主要的thread_pool有generic、index、get、bulk、 search等,可用通过GET _nodes/thread_pool?

阅读全文

Python GIL与线程安全

python GIL与多线程 GIL: Global Interpreter Lock(全局解释器锁),python虚拟机一级的互斥机制,用来保护资源的互斥访问,尤其是python对象的引用计数。 python代码执行 获得GIL 执行代码直到被阻塞或N条指令执行之后(py3:超时时间)被python 虚拟机调度 释放GIL 何时挂起当前线程:被阻塞或N条指令执行之后(py3:超时时间15ms) 如何选择等待的线程进行调度:由底层操作系统决定 python多线程机制是在GIL基础上实现的 python的多线程机制建立在操作系统的原生线程的基础之上 Thread safe in python Python线程安全与传统的java、c有很大不同,python的很多操作都是原子的,例如sort函数本身是原子操作,不会被其他线程看到排序一半的list;而有一些操作不是原子的,例如+= n=0 def add(): global n n += 1 import dis #将python byte code转为助记符号 dis.dis(add) 3 0 LOAD_GLOBAL 0 (n) 3 LOAD_CONST 1 (1) 6 INPLACE_ADD 7 STORE_GLOBAL 0 (n) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE 操作步骤为: 加载n到栈 加载常量n到栈 将两者相加 将结果付给n 由于操作不是原子的,python解释器可能在某一步被抢占,造成不一致的情况,执行以下代码,将不一定会得到100 threads = [] for i in range(100): t = threading.

阅读全文

ElasticSearch配置滚动更新

起因 最近Logstash经常打印如下日志内容,虽然只是INFO级别的错误但还是引起了我的注意,大概意思是ES的bulk thread pool大小为32已经满负荷,队列也满了,所以拒绝了Logstash的bulk请求 [2018-06-23T08:00:47,281][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 429 ({"type"=>"es_rejected_execution_exception", "reason"=>"rejected execution of org.elasticsearch.transport.TransportService$7@177d229b on EsThreadPoolExecutor[bulk, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@66a1a8c3[Running, pool size = 32, active threads = 32, queued tasks = 1019, completed tasks = 832616617]]"}) 解决思路 扩大处理bulk的thread pool线程数量 当前使用的服务器CPU核数为176(cat /proc/cpuinfo),而在ES源码中为了避免引起Java oom线程数会取min(32, 核数),所以造成默认的thread_pool.bulk.size为32,为了扩大线程容量需在ES中添加以下配置 processors: 96 thread_pool.bulk.size: 96 增加等待队列长度 thread_pool.bulk.queue_size: 3000 更新配置 这些配置不能通过ES Setting API来更改,只能通过滚动重启的方式,下面简单记录下过程 禁止分配分片 curl -X PUT "ES_HOST:9200/_cluster/settings" -H 'Content-Type: application/json' -d' { "transient": { "cluster.

阅读全文

ELK集群2.x到5.6升级记录

考虑到目前使用的ELK集群版本与开源版本的版本差距有点大,而ELK5.6相较2.3版本性能有较大提升,尤其是Logstash grok插件,最近对测试环境的两个ELK集群进行了升级,对升级过程进行一个记录;升级主要参考了官方文档 当前系统运行版本 filebeat:1.2.3 kibana:4.5.1 logstash:2.3.2 elasticsearch:2.3.3 JVM: 1.7 升级顺序 jvm(略) elasticsearch kibana logstash beats 升级Elasticsearch 升级之前 升级前使用Elasticsearch Migration Plugin查看潜在问题 最好先在测试环境升级ELK 在升级之前先备份数据 升级(跨大版本整个集群需重启) 禁止自动分配分片,在停止elasticsearch时减少不必要的I/O curl -XPUT 'localhost:9200/_cluster/settings?pretty' -H 'Content-Type: application/json' -d' { "persistent": { "cluster.routing.allocation.enable": "none" } }' 同步刷新以加快分片恢复 curl -XPOST 'localhost:9200/_flush/synced?pretty' 停止并升级各个节点(安装新的rpm或deb,更新配置文件,配置文件有较大改动) /etc/init.d/elasticsearch stop apt-get pruge elasticsearch(所有deb包已在本地apt源中,删除原配置文件) apt-get install elasticsearch=5.6.5 升级插件(需删除旧的插件) /usr/share/elasticsearch/bin/elasticsearch-plubin remove license /usr/share/elasticsearch/bin/elasticsearch-plubin remove marvel /usr/share/elasticsearch/bin/elasticsearch-plubin install x-pack 启动集群各个节点,保证所有节点均加入集群(优先启动master node)

阅读全文

ElasticSearch索引类型映射

最近接手维护了几个ELK集群,对接的是IaaS、PaaS服务日志,简单的ELK架构,通过filebeat采集日志,发送到logstash结构化日志然后发送到ElasticSearch,用户可以通过Kibana查看服务日志定位问题、做一些性能分析图表等,同时利用elastalert做日志报警。 在ElasticSearch须要对用户的索引建立合适的类型映射(尤其是int类型),才可以在kibana中对数据进行分析,关于ES的映射类型可以看这里,需指出的是一旦某个field字段类型确定就很难更改该字段的类型(需reindex)。 Logstash将非结构化数据转化为结构化数据,通过JSON将数据发送给ElasticSearch,所有字段都会被当作string来处理,而ElasticSearch在自动判断字段类型建立映射这方面做的不足,与我们需求不符,那么如何正确建立索引类型映射呢? 一、通过Logstash的grok、mutate确定字段类型 grok 根据grok官方文档,在grok正则表达式后可以添加一个数据类型,默认是string类型,如果你想使字段类型为int,你可以在表达式后加int,例如%{NUMBER:num:int},那么num字段会从string类型变为int类型,目前只支持int和float。 mutate 通过mutate可以将field转化为integer、float、string,例如: filter { mutate { convert => { "num" => "integer" } } } 二、ElasticSearch mapping template 映射(mappings)决定了一个字段(field)如何被ElasticSearch解释、存储,例如数据{“ip”:“223.5.5.5”}发送给ES,ES会将ip字段存储为string类型,而不是ip类型,不能做IP范围查询同时造成存储空间浪费、查询效率低等。**不管在Logstash如何转换类型,ElasticSearch不会知道你的用意除非你正确映射。**所有整型会存为long,小数会存为float或double,关于最小类型可以看这里,使用integer而不是long会有效的减少ELasticSearch负担。 映射模版 编写模版文件my_template.json { "index_patterns" : "index*", "version" : 1, "settings" : { "index.refresh_interval" : "5s" }, "mappings" : { "_default_" : { "properties":{ "host": { "type" : "string"}, "ip": {"type" : "ip"}, .... } } } } 上传template.

阅读全文

Logstash过滤插件grok正则解析

Logstash过滤插件grok正则解析 一、grok介绍 grok是Logstash中用来解析非结构化日志数据,将日志转化为可查询的结构化数据的最佳方法,可以用来处理syslog日志、apache等webserver日志、mysql日志以及用户自定义日志。 Logstash自带有120多种预定义好的正则表达式方便用户使用,你可以在这里查看这些正则表达式,你也可以添加自己的匹配规则。 有两个网站可以帮助我们来构建正则表达式去匹配我们的日志: http://grokdebug.herokuapp.com http://grokconstructor.appspot.com (推荐) 二、grok基础 grok匹配模式语法为:%{SYNTAX:SEMANTIC:TYPE} SYNTAX: 正则表达式、预定义的正则表达式名称 SEMANTIC: 标识符,标识匹配后的数据 TYPE: 可选的类型,目前支持int、float 例如:NUMBER可以匹配3.44,IP可以匹配:192.168.21.2 一个复杂的日志格式如下: 192.168.21.2 GET /index.html 15823 0.023 grok匹配模式可以为: ${IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} 更加实际的,该条日志可能来自一个文件: input { file { path => "/var/log/http.log" } } filter { grok { match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" } } } 在grok过滤后,可以得到额外一下字段: client: 192.168.21.2 method: GET request: /index.html bytes: 15823 duration: 0.023 grok中的正则表达式 Grok采用了Oniguruma正则表达式库,在on the Oniguruma site看到支持的正则语法。

阅读全文

ansible自动化部署配置工具

ansible自动化部署配置工具 初识ansible 简介 ansible是运维自动化工具,可以实现系统配置、软件部署,可以通过编排实现更高级的功能如持续集成、热更新等;ansible具有简单易用、安全、agentless等特点,通过ssh来完成与管理节点的交互。 inventory ansible管理的主机信息称为inventory,默认存储在/etc/ansible/hosts,也可以在运行时通过-i 指定inventory文件位置,通常为ini格式,如下: [jumpserver] 44.33.22.11:1024 ansible_ssh_user=xxx # xxx用户ssh端口1024,2.0后参数变为ansible_user [other] 192.168.1.[2:255] # 范围2-255 [localhost] localhost ansible_connection=local 处于[]中的为组名,一个节点可以在多个组下,组下为机器名可指定端口与参数,支持的参数详情见文档。 patterns: ansible执行ad-hoc 命令的基本格式如下: ansible <pattern_goes_here> -m <module_name> -a <arguments> ansible中的模式patterns决定了inventory中哪些主机将执行指定命令,默认是all(*)所有机器,可以指定多个组的集合如other:localhost(并集) other:!localhost(差集)、other:&localhost(交集)等 ad-hoc命令 ad-hoc命令是指执行简单短小的、无需保存结果的任务 # 查看localhost组的uptime,-m指定模块,默认为command, -a指定参数, -f并发数 ansible localhost -m command -a "/usr/bin/uptime" # -u username切换登录用户 --become 切换到root执行 --become-user otheruser 切换到其他用户执行 ansible localhost -a "/usr/bin/uptime" -u sa # 文件传输 ansible jumpserver -m copy -a "src=https://itech.red/etc/hosts dest=/tmp/hosts mode=600" # 包管理 ansible jumpserver -m yum -a "name=vim state=present" #确保vim包已安装 ansible jumpserver -m yum -a "name=vim state=absent" #vim包卸载 # 用户管理 ansible jumpserver -m user -a "name=xiao password=xxx" #增加用户xiao # 服务管理 ansible jumpserver -m service -a "name=httpd state=restarted" # 信息收集 ansible jumpserver -m setup 常用配置项

阅读全文

作者的图片

沉下心,多坚持

系统工程师

杭州