Elasticsearch写入优化

收到工单 用户提工单到L2说写入消息堆积了,第一时间检查ElasticSearch这边的日志和监控,把一百多个节点的日志都遍历看了一遍,并没有看到任何异常的关键字,再把 Grafana 监控看了一个遍,也没有任何明显异常的指标,只有少数几个data节点超出85%水位,没法办法只能从写入端的日志去着手了,刚开始就看到每分钟内多次的 http 429报错,还有就是socket timeout的报错,从下午排查到晚上,实在ElasticSearch这边没有任何异常,客户那边也上会了,问了下,你们这个重试是怎样的?说等待十秒重试一次吧,另外客户是通过Bulk API来批量发送请求的,但是每次Bulk发送的大小不固定,小于2000直接发送,大于2000截断发送(这个肯定是不合理的,后面再讲),这个等待重试,加入ElasticSearch因为写入请求太多导致阻塞,那么简单的等待重试,肯定是解决不了任何问题的,当天就推荐用户修改为退避式重试,修改完后的写入端日志里,不再有429的报错了,但是还有会有socket timeout的报错,结合之前注意到的,猜想是请求发送的次数太多了,然而单个Bulk的数据量很明显不到推荐值,没有被充分利用,官方推荐的Bulk大小是5-15MB,然而目前的情况是,几十条甚至一两条的写入请求也会被直接发送出去。推荐用户修改Bulk单次提交数据量后,仍然没有任何缓解的效果,消息队列消费不完,还是经常性出现堆积。data节点的配置是16C64G,检查了写入线程数也就是默认是16,这个没法改,最大也就改到17,写入线程队列是6.X ElasticSearch的默认值200,这个改大也不能解决消费慢的问题,只能让更多的线程在排队。其他方面,不同索引的刷新配置refresh_interval设置的30-60s,这个也是一个合理的值,其他的translog落盘配置,检查过也都是默认值。唯一一处疑点就是mapp...

创建: 2024-11-16 | 字数: 3818字 | 时长: 8分钟

香港三日游+港卡记录

2024年开始一直有在支付宝上买纳斯达克和标普的指数基金,另外由于上次讲到的,X被我养成了,所以经常能看到很多牛人在谈论美股,我也开始了解了一些,之前也看有人在玩美股,据说最简单的办法就是办一张港卡,所以就有了这次旅行。 不得不说,想说在查攻略这方面还是挺不错的,开始申请港澳通行证办理签注,然后花费两天年假,提前去广东深圳, 带上爸妈一起去旅游,虽然对于我不仅仅是旅游。 办理通行证各个地方各个省份的入口不一样,但流程大多相同,在网上预约,然后去线下填表拍照录指纹,然后会有同志问你去干什么,至于签注可以根据自己的需要选择不同的类型,另外团队签和个人签这个没什么区别,不用太在意。 到达深圳以后,在酒店休息一晚,考虑如何去到香港可以选择轮渡/高铁/公交,我选择的是高铁速度最快通关最便捷,从深圳北站前往香港西九龙站,只需要不到20分钟人民币¥75,我没有体验普通的公交和口岸的过关方式,据说排队的人会很多,通关会耗时更久。 像坐普通的高铁一样,从深圳北出发到达香港西九龙入关,然后你录入的的指纹就可以发挥作用了, 按下指纹后,校验通过会给你一张过关小票,这个小票一定要留好, 后面办理港卡的时候会用到。 从西九龙站出来就能够看到维多利亚港, 对面的楼认识的不多,但是牛逼就完事了。 我是六点多从深圳出发, 在香港的交通方面可以直接使用支付宝,需要提前在支付宝的左上角切换地址为香港,然后领取交通卡。 大部分的公交地铁都可以直接刷码, 只在三天的旅途中遇到了一辆司机说“请去下一辆,不支持支付宝”。 乘坐地铁前往葵芳, 从地铁站出来大概走不到500米就到达汇丰葵芳分行,因为老人出站时刷了码,但是反应慢了没出来,联系站务人员花费了一些时间。 到达时已经8:30多了,这时候银行门口已经排满了人,大概是20多人, 等着来都来了的原则,只能开始排队了。 9:00准时开门, 这里的银行不像内地那么气派,面积不大,也没有前台,只有门口一个业务员...

创建: 2024-10-09 | 字数: 5216字 | 时长: 11分钟

记录被喝茶这件事

常在河边走 特意打开Twitter看了一下,我是21年3月份注册的,现在看来马斯克收购推特,然后改名为X对我来说是一个利好,因为我只需要在地址栏敲一个X就能够联想到推特的域名(因为我已经把推特的从我的iTab书签页里面删掉了),为什么要删掉?就是这篇博文的原因。 18,19年那时候我会上油管,看一下伟大祖国最近的军事发展科技成果,或者是关注一下一些旁征博引的野史,那时候推特对我来说和脸书一样,乏味,没啥意思,后来当它知道我是干什么的?个性化推荐开始 才开始觉得有点意思,至少比国内的平台更自由开放,我看到了很多程序员的分享,包括当然也有键政派,也有女菩萨派,还有裸聊派…… 崭露头角 直到22年推荐了我一个李老师不是李老师的账号,这个人进入到我的视野 我发现我好像看到了什么不该看的,让我想起来那么一个图,一个猪趴在围墙上,看见几个人在杀另一只猪。 当然上网冲浪这么久也不是第一次看到这样的内容,虽然他一直出现在我的timeline里面,但是我从来没有想过要关注他。 登峰造极 22,23年我在北京,当时疫情发生了一些事情,一些血气方刚的大学生,上海也发生了一些事情,估计那段时间他也挺忙的,各种投稿,我都看了,但我没有任何表示,我也没关注他,直到有一天看他发了个帖子说不要关注他,因为有人因为关注了他被约谈了。好家伙,我心想幸好我没关注😅 与工作搏斗 2024年,这份工作不像之前那么轻松,上班已经消耗了我一天的精力,下班只想躺着刷手机,在一次网上冲浪的过程中我鬼使神差就点开了他的主页,看了一下他最近发的但我没有关注到的内容,实际上我已经疲于应对我的工作了,甚至都没有精力去关注他发的内容,因为我关注了又能怎样,我解决不了任何问题。如果是别的任何一个正常的推特用户,那么仅仅是白白消耗了我0.01卡的能量点一个没有任何意义的关注而已,但偏偏是他,让我在接下来的半个月里被各种找不到地方吐的恶心。 还是湿了鞋 那天早上刚...

创建: 2024-08-10 | 字数: 1849字 | 时长: 4分钟

git合并方法学习

用字符画描述git的合并方法 1. 合并(Merge) main 分支 A---B---C \ dev 分支 D---E---F 在 main 分支上执行 `git merge dev` 后: main 分支 A---B---C-----------G <- (G 是合并提交) \ / dev 分支 D---E---F 2. 变基(Rebase) main 分支 A---B---C \ dev 分支 D---E---F 在 dev 分支上执行 `git rebase main` 后,再在 main 分支上执行 `git merge dev`: main 分支 A---B---C---D'---E'---F' 3. 压缩合并(Squash and Merge) main 分支 A---B---C \ dev 分支 D---E---F 在 main 分支上执行 `git merge --squash dev` 后,再执行提交: main 分支 A---B---C-----------G' <- (G' 是一个新的提交,合并来自 D、E 和 F 的变更) 4. 拣选提交(Cherry-pick)(不是标准合并所有更改的方法) main 分支 A---B---C \ dev 分支 D---E---F 在 main 分支上对 dev 分支的每个提交执行 `git cherry-pick <提交哈希值>`: main 分支 A---B---C---D'---E'---F' <- (每个提交被逐一复制) 合并方法的对比表格 方法 特点 适用场景 结果 Merge 保留所有分支的历史 标准的合并操作,适用于大多数场景 创建一个新的合并提交 Rebase 使历史线性化 个人分支上的工作或清洁历史 不保留原始分支提交的顺序 Squash and Merge 将所有更改压缩为一个提交 当你想要简化复杂分支的历史时 一个新的单一提交 Cherry-pick 手动选择特定提交 只合并某些特定的更改 对选择的每个提交创建新的提交 请注意,这些方法中,Merge 和 Rebase 是最常用的策略来整合一个开发分支(如 dev)到主分支(如 main)。Squash and Merge 通常用于在合并之前压缩多个提交以保持清洁的历史。Cherry-pick 方法并不是一个真正的分支合并策略,它只是用于将选定的提交从一个分支复制到另一个分支,因此它不应用于将一个完整的功能分支合并到主分支的场景。

创建: 2024-03-26 | 字数: 599字 | 时长: 2分钟

祝大哥今年发大财日进斗金

好久没有更新了,借此机会更新一下,老早就看了天气预报今天会下雨,于是就做好了不出门的准备,一觉睡到十点多,一看窗外也没有下雨啊,但是还是照计划行事吧,开启懒狗模式,饿了点了个外卖,想起几天前就是315,又爆了什么猛料呢?梅菜扣肉,某奶茶……触目惊心,可是仔细一想,央视那些记者真是习得东亚小岛传统技能忍者术啊,那叫一个能忍,暗中调查一年,然后在第二年的315憋个大招?已经不知道用什么语言来表达了。说回点外卖,自从去年在北京住青旅找工作的那段时间,那时候在蓝鸟上看到一句话说“此时北上广的青旅里,挤满了找工作的年轻人。”我已经很少很少点外卖了,这次也是懒狗模式的缘故,美团送了个张30-10的券,点了个杨国福麻辣烫,上一次点外卖也是这家,而且内容也都类似(千张,莴苣片,油豆皮,青菜……),我从不或者很少选肉、肉丸子,因为自从我听了一句话叫做“好肉不做馅”就一直把这句话放在心里。 外卖到了,收到外卖员的电话了,打电话说外卖到了,我说好,出门去拿,打开门,他在门口,是一个看起来三十多不到四十的中年人,按照的点外卖经历,有时候,你接到电话,他其实才到楼下,等你想起来再去拿,其实外卖已经在门口,人早就走了。要么就是你收到电话是,外卖已经给你扔门口了,他也走远了,但今天不一样,他就在门口站着,我打开门接过外卖,说了声谢谢,就回屋了。其实到此为止也不至于我今天下午想这么多东西,以至于想写点东西。 下午,闲得蛋疼并不是卷的我,出门骑车去公司的路上,我收到一个电话,我一看浙江杭州号码,接过来,对面说“大哥好,我是给你送麻辣烫的那个外卖员,麻烦您能给我一个五星好评吗?帮我过一下新手的任务,祝大哥今年发大财日进斗金。”,我说好,其实我知道按照我的性格,当他说是过新手任务的时候,我就会决定帮他这个忙了。后面那句直接让我楞了一秒,我才憋出一句”你也一样“,虽然平时工作中,和外部一些初入职场的年轻人对接时,他们...

创建: 2024-03-17 | 字数: 937字 | 时长: 2分钟

ElasticSearch中熔断器

Elasticsearch Service 提供了多种官方的熔断器(circuit breaker),用于防止内存使用过高导致 ES 集群因为 OutOfMemoryError 而出现问题。Elasticsearch 设置有各种类型的子熔断器,负责特定请求处理的内存限制。此外,还有一个父熔断器,用于限制所有子熔断器上使用的内存总量。 Circuit breaker settings 断路器设置 Elasticsearch contains multiple circuit breakers used to prevent operations from causing an OutOfMemoryError. Each breaker specifies a limit for how much memory it can use. Additionally, there is a parent-level breaker that specifies the total amount of memory that can be used across all breakers. Elasticsearch 包含多个断路器,用于防止操作导致 OutOfMemoryError。每个断路器都指定了其可以使用的内存量的限制。此外,还有一个父级断路器,用于指定可在所有断路器中使用的内存总量。 Except where noted otherwise, these settings can be dynamically updated on a live cluster with the cluster-update-settings API. 除非另有说明,否则可以使用 cluster-update-settings API 在实时集群上动态更新这些设置。 For information about circuit breaker errors, see Circuit breaker errors. 有关断路器错误的信息,请参阅断路器错误。 下面提到的静态和动态的意思是,这个配置参数的属性 动态设置(Dynamic Settings): 可以使用集群更新设置API在运行中的集群上进行配置和更新。 在未启动或已关闭的节点上,也可以通过elasticsearch.yml文件进行本地配置。 静态设置(Static Settings): 只能在未启动或已关闭的节点上通过elasticsearch.yml文件进行配置。 必须在集群中的每个相关节点上进行设置。 主要用于配置静态的集群设置和节点设置。 静态设置的配置只在节点启动时生效,不会受到集群运行时的影响。 Parent circuit breaker父断路器 The parent-level breaker can be configured with the following settings: 可以使用以下设置配置父级断路器: indices.breaker.total.use_real_memory (Static) Determines whether the parent breaker should take real memory usage into account (true) or only consider the amount that is reserved by child circuit breakers (false). Defaults to true. (静态)确定父断路器是应考虑实际内存使用情况 (true) 还是仅考虑子断路器保留的内存量 (false)。默认值为 true。 indices.breaker.total.limit (Dynamic) Starting limit for overall parent breaker. Defaults to 70% of JVM heap if indices.breaker.total.use_real_memory is false. If indices.breaker.total.use_real_memory is true, defaults to 95% of the JVM heap. (动态)整体母断路器的起始限制。如果 JVM 为 false,则默认为 JVM 堆的 70%indices.brea...

创建: 2023-11-20 | 字数: 2523字 | 时长: 6分钟

Elasticsearch稳定性介绍

Elasticsearch 的团队致力于不断改进 Elasticsearch 和 Apache Lucene,以保护您的数据。与任何分布式系统一样,Elasticsearch 非常复杂,每个部分都可能遇到需要正确处理的边缘情况。我们将讨论在面对硬件和软件故障时,为改进 Elasticsearch 在健壮性和弹性方面所做的持续努力。 提升ElasticSearch的弹性:https://www.elastic.co/cn/videos/improving-elasticsearch-resiliency ElasticSearch和弹性:https://www.elastic.co/cn/elasticon/conf/2016/sf/elasticsearch-and-resiliency 参考资料:https://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html 本文不是ElasticSearch的Release docs,只关注与ElasticSearch在弹性/稳定性方面的进展。 V5.0.0 使用两阶段提交进行集群状态发布 Elasticsearch中的主节点会持续监控集群节点,并在某个节点无法及时响应其PING请求时将其从集群中移除。如果主节点剩下的节点过少,它将主动放弃主节点的角色,然后开始新的主节点选举过程。当网络分区导致主节点失去许多从节点时,在检测到节点丢失并且主节点下行之前,有一个很短的时间窗口。在这个时间窗口内,主节点可能会错误地接受和确认集群状态变更。为了避免这种情况,我们在集群状态发布中引入了一个新的阶段,其中提议的集群状态会发送给所有节点,但尚未提交。只有在足够多的节点主动确认更改后,更改才会被提交,并向节点发送提交消息#13062。A master node in Elasticsearch continuously monitors the cluster nodes and removes any node from the cluster that doesn’t respond to its pings in a timely fashion. If the master is left with too few nodes, it will step down and a new master election will start.When a network partition causes a master node to lose many followers, there is a short window in time until the node loss is detected...

创建: 2023-11-16 | 字数: 7371字 | 时长: 15分钟

随便写点什么吧

胡言乱语【1】 昨天去了西溪湿地公园,在网络上搜了下攻略发现,有收费区和免费区,而且景色还没什么两样,果断选择无成本的方案,免费的就是最贵的,结果就是人挤人,还有二货明明走在机动车道了,还不满足,还要并排着走(大有不服你来撞我的意思)。开车的人还不能鸣笛,只能找机会借对面的道绕过去,速度缓慢,走走停停,我心想要是开个油车手动挡走这条路简直就是地狱级。 胡言乱语【2】 碰见一个三口之家朝我走过来,爸爸手里拿着两片叶子,放在嘴边吹响了,小男孩说,看来爸爸在农村长大还是有用的(会吹叶子做的哨子),爸爸和妈妈都笑了,问他那你现在在哪里啊?然后我已经走远了。一位寒窗苦读艰苦奋斗的农村青年终于在城市站稳脚跟,周末带着老婆孩子去感受城市里的农村(湿地)。 胡言乱语【3】 杭州是新一线城市,武汉也是新一线城市,武汉房价比不过杭州,武行东湖也比不过杭州西湖,在历史气息这块我想还不能直接妄下结论,虽然没有像杭州那样留下一首忆江南的诗,但是近代史很多关键性的事件也是在武汉发生。 关于西溪湿地里高庄的历史 高庄又名西溪山庄,始建于清顺治十四年(1657)至康熙三年(1664年)之间,是清代文人高士奇在西溪的别墅。 高士奇,杭州人,其学识渊博,能诗文,擅书法,精考证,善鉴赏,被清人比作李白、宋濂一流人物,所藏书画甚富,康熙二十八年(1689),康熙南巡时,曾临幸西溪山庄,并赐“竹窗”二字和诗一首:“花源路几重,柴桑出沃土。烟翠竹窗幽,雪香梅岸古”。 传说康熙曾南巡到西溪,独与高士奇泛小舟至高庄观览良久,高士奇将康熙驻趾之亭取名为“宸览亭”亭柱上有楹联:“翠辇曾停红莲依旧,宸游不再斯事难逢。”居中的石碑上四个大字“高庄宸迹”,此处就是当年康熙皇帝留在西溪的胜景遗迹。 因为是在免费区,人更多了,大部分都是穿着古装在摆拍的,不得不佩服妹子的专业能力,还有道具的书,捧在手里,拿着小扇子。 而我只是看着水池边的白条,但凡有个网兜,...

创建: 2023-10-29 | 字数: 816字 | 时长: 2分钟

Docker Compose 运行 Elastic Stack 8.X

材料准备 如题,使用Docker Compose 运行Elastic Stack 8.X,五个月前还在前司做7.9版本的ELK迁移,如今已经是前司了,当时总共不到20TB,最近问前同事数据量已经到40TB了,而且根据她发我的截图来看,三千多个索引,副本分片却只有两千多,不操心了,事不关己高高挂起,反正现在负责ELK的是新来的陌生人。今天看已经发到8.10版本了,来装一个感受下新特性。 官方Docker Compose 官方安装指引文档 额外操作参考博客 version: "2.2" services: setup: image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs user: "0" command: > bash -c ' if [ x${ELASTIC_PASSWORD} == x ]; then echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; exit 1; elif [ x${KIBANA_PASSWORD} == x ]; then echo "Set the KIBANA_PASSWORD environment variable in the .env file"; exit 1; fi; if [ ! -f config/certs/ca.zip ]; then echo "Creating CA"; bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; unzip config/certs/ca.zip -d config/certs; fi; if [ ! -f config/certs/certs.zip ]; then echo "Creating certs"; echo -ne \ "instances:\n"\ " - name: es01\n"\ " dns:\n"\ " - es01\n"\ " - localhost\n"\ " ip:\n"\ " - 127.0.0.1\n"\ " - name: es02\n"\ " dns:\n"\ " - es02\n"\ " - localhost\n"\ " ip:\n"\ " - 127.0.0.1\n"\ " - name: es03\n"\ " dns:\n"\ " - es03\n"\ " - localhost\n"\ " ip:\n"\ " - 127.0.0.1\n"\ > config/certs/instances.yml; bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; unzip config/certs/certs.zip -d config/certs; fi; echo "Setting file permissions" chown -R root:root config/certs; find . -type d -exec chmod 750 \{\} \;; find . -type f -exec chmod 640 \{\} \;; echo "Waiting for Elasticsearch availability"; until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done; echo "Setting kibana_system password"; until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; echo "All done!"; ' healthcheck: test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"] interval: 1s timeout: 5s retries: 120 es01: depends_on: setup: condition: service_healthy image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs - esdata01:/usr/share/elasticsearch/data ports: - ${ES_PORT}:9200 environment: - node.name=es01 - cluster.name=${CLUSTER_NAME} - cluster.initial_master_nodes=es01,es02,es03 - discovery.seed_hosts=es02,es03 - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - bootstrap.memory_lock=true - xpack.security.enabled=true - xpack.security.http.ssl.enabled=true - xpack.security.http.ssl.key=certs/es01/es01.key - xpack.security.http.ssl.certificate=certs/es01/es01.crt - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.enabled=true - xpack.security.transport.ssl.key=certs/es01/es01.key - xpack.security.transport.ssl.certificate=certs/es01/es01.crt - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.verification_mode=certificate - xpack.license.self_generated.type=${LICENSE} mem_limit: ${MEM_LIMIT} ulimits: memlock: soft: -1 hard: -1 healthcheck: test: [ "CMD-SHELL", "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", ] interval: 10s timeout: 10s retries: 120 es02: depends_on: - es01 image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs - esdata02:/usr/share/elasticsearch/data environment: - node.name=es02 - cluster.name=${CLUSTER_NAME} - cluster.initial_master_nodes=es01,es02,es03 - discovery.seed_hosts=es01,es03 - bootstrap.memory_lock=true - xpack.security.enabled=true - xpack.security.http.ssl.enabled=true - xpack.security.http.ssl.key=certs/es02/es02.key - xpack.security.http.ssl.certificate=certs/es02/es02.crt - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.enabled=true - xpack.security.transport.ssl.key=certs/es02/es02.key - xpack.security.transport.ssl.certificate=certs/es02/es02.crt - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.verification_mode=certificate - xpack.license.self_generated.type=${LICENSE} mem_limit: ${MEM_LIMIT} ulimits: memlock: soft: -1 hard: -1 healthcheck: test: [ "CMD-SHELL", "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", ] interval: 10s timeout: 10s retries: 120 es03: depends_on: - es02 image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} volumes: - certs:/usr/share/elasticsearch/config/certs - esdata03:/usr/share/elasticsearch/data environment: - node.name=es03 - cluster.name=${CLUSTER_NAME} - cluster.initial_master_nodes=es01,es02,es03 - discovery.seed_hosts=es01,es02 - bootstrap.memory_lock=true - xpack.security.enabled=true - xpack.security.http.ssl.enabled=true - xpack.security.http.ssl.key=certs/es03/es03.key - xpack.security.http.ssl.certificate=certs/es03/es03.crt - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.enabled=true - xpack.security.transport.ssl.key=certs/es03/es03.key - xpack.security.transport.ssl.certificate=certs/es03/es03.crt - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt - xpack.security.transport.ssl.verification_mode=certificate - xpack.license.self_generated.type=${LICENSE} mem_limit: ${MEM_LIMIT} ulimits: memlock: soft: -1 hard: -1 healthcheck: test: [ "CMD-SHELL", "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", ] interval: 10s timeout: 10s retries: 120 kibana: depends_on: es01: condition: service_healthy es02: condition: service_healthy es03: condition: service_healthy image: docker.elastic.co/kibana/kibana:${STACK_VERSION} volumes: - certs:/usr/share/kibana/config/certs - kibanadata:/usr/share/kibana/data ports: - ${KIBANA_PORT}:5601 environment: - SERVERNAME=kibana - ELASTICSEARCH_HOSTS=https://es01:9200 - ELASTICSEARCH_USERNAME=kibana_system - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt mem_limit: ${MEM_LIMIT} healthcheck: test: [ "CMD-SHELL", "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'", ] interval: 10s timeout: 10s retries: 120 volumes: certs: driver: local esdata01: driver: local esdata02: driver: local esdata03: driver: local kibanadata: driver: local 步骤分析 来欣赏下官方文档里面都干了些啥吧 创建了一个卷用来存储各种证书 判断ElasticSear...

创建: 2023-09-28 | 字数: 2279字 | 时长: 5分钟

记一次Prometheus的离奇经历

前情提要 书接上回,为了获取客户的Prometheus的监控数据,我写了个脚本用来通过API获取监控数据,然后转换成Open metric格式以方便,传输和导入,代码如下。 import datetime import subprocess import requests import sys """ http://localhost:9090 """ prometheus_url = input("请输入Prometheus链接: ") username = input("请输入用户名: 如无认证,请回车跳过") password = input("请输入密码: 如无认证,请回车跳过") print("下面的两个变量只需填写一个或者不填使用默认值") step = input("请输入每两个数据点间隔(单位秒,建议为5的倍数): ") hours = input("请输入往前查询的小时数(单位小时,建议不填): ") auth = None metric_param = "e" # 将查询出所有带有elasticsearch的指标 if username != "" and password != "": auth = (username, password) # 检查用户输入是否为数字 def is_number(value): try: int(value) return True except ValueError: return False # 如果用户同时设置了hours和step,按用户的输入值查询 if hours != "" and step != "": hours = int(hours) step = int(step) print("将查询过去{}小时的数据,步长为{}秒".format(hours, step)) else: # 如果用户没有输入hours和step,使用默认值 if hours == "" and step == "": print("将使用默认值查询") hours = 30 step = 10 elif hours != "": hours = int(hours) # 根据用户输入的hours计算step step = int(60 * 60 / (11000 / hours)) + 1 print("将查询过去{}小时的数据,步长为{}秒".format(hours, step)) elif step != "": step = int(step) # 根据用户输入的step计算hours hours = int(11000 / (60 / step) / 60) print("将查询过去{}小时的数据,步长为{}秒".format(hours, step)) else: print("输入的小时数和步长必须为有效的数字。") sys.exit(1) end_time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") query_time = datetime.datetime.now() - datetime.timedelta(hours=hours) start_time = query_time.strftime("%Y-%m-%dT%H:%M:%SZ") series = requests.get('{}/api/v1/label/__name__/values'.format(prometheus_url), auth=auth) if series.status_code != 200: print("查询失败,请检查{}/api/v1/label/__...

创建: 2023-09-25 | 字数: 5507字 | 时长: 11分钟