gearman使用心得

news2024/12/25 22:28:20

gearman基础

工作原理

在这里插入图片描述

部署架构

本质上,gearman可以认为是一个分布式任务队列,client是生产者,worker则是消费者。gearman并不主动分发任务,而是由worker到它那里去取任务执行,所以它采用的是类似kafka的pull消费模式。

启动、停止服务

service gearmand start

service gearmand restart

service gearmand stop

修改gearmand启动参数

配置文件路径在:

/etc/init.d/gearmand

管理命令

(echo status; sleep 0.1) | nc 127.0.0.1 4730

结果形如:

simu    0       0       2
msg     0       0       0
test    0       0       6

每列说明如下:

函数名: job的函数名
Number in queue:队列里该函数下的job总数,包含当前正在运行的job
Number of jobs running: 该函数当前正在运行的job数
Number of capable workers: 可以做该job的worker总数

如果系统比较繁忙的话,Number of jobs running的数值会接近Number of capable workers;Number in queue可能会大于Number of capable workers。此时我们应该增加Worker的数量,反之则应该考虑减少Worker的数量。

gearman优势

  1. 跨语言的调用,worker可以用多种语言来写。
  2. 跨平台,client可以在linux上,而worker甚至可以在windows上。

进阶

持久化

对于任务队列持久化的问题,是一个值得考虑的问题。持久化必然影响高性能。gearman支持后台工作任务的持久化,支持drizzle、mysql、memcached的持久化。对于client提交的background job,Job server除了将其放在内存队列中进行派发之外,还会将其持久化到外部的持久化队列中。一旦Job server发生问题重启,外部持久化队列中的background job将会被恢复到内存中,参与Job server新的派发当中。这保证了已提交未执行的background job不会由于Job server发生异常而丢失。并且我测试发现如果开启了持久化,那么background工作任务会先将工作任务写到持久化介质,然后再入内存队列,再执行。非background工作任务,由于client与job server是保持长连接的状态,如果工作任务执行异常,client可以灵活处理,所以无须持久化。

background任务的状态获取

一个background任务的查询结果形如:

<GearmanJobRequest task='simu', unique='bfa0751a74bb0b38b01e07bc90557757', priority=None, background=True, state='CREATED', timed_out=False>
Job bfa0751a74bb0b38b01e07bc90557757 finished!  Result: CREATED - None,  Data:deque([]), Status:{'numerator': 0, 'time_received': 1587369989.1067996, 'running': True, 'known': True, 'denominator': 0, 'handle': 'H:camera-vm68:217'}
Job bfa0751a74bb0b38b01e07bc90557757 finished!  Result: CREATED - None,  Data:deque([]), Status:{'numerator': 0, 'time_received': 1587369991.1361463, 'running': False, 'known': False, 'denominator': 0, 'handle': 'H:camera-vm68:217'}

可见,一个任务一旦被设置为background执行,最后只能了解它是否执行完了,结果成功与否及中间进度都无法获得,client的get_job_status接口仅能用于非background任务的状态查询。

worker踢出

现象:

某个worker出现快速失败,然后又不停的到队列里拿任务,最后导致任务的大面积失败。

由于gearman server不主动分发,而是由worker“任性自为”,所以gearman server自身并无一个踢出快速失败worker的机制,需依赖于gearman client或worker来做这个事情。

具体说来,gearman client可以统计worker在一段时间内的失败次数、查询worker失败信息,来发现可能是快速失败的机器。另一方面,worker自己也可以根据错误信息来进行自我隔离。

tcp保活

起因:TCP对于非正常断开的连接并不能侦测到(比如网线断掉)。

我们先说一下TCP关闭连接时的动作,比如A和B通信,A向B发送一个FIN,B返回一个FIN,双方各自把单边的连接断开,整个TCP连接就结束了。如果,A突然崩溃了,这个FIN发不出去,没有保活机制,B可能就永远发现不了。

一般情况下,我们重启机器或者kill进程,socket文件句柄关闭,底层的TCP协议栈会为我们自动发送FIN,但接收端不一定能收到,比如下面的例子:

We are seeing some TCP behavior that we have not seen before. Normally when we kill a task that has a link over the local interface to another local task, in tcpdump we see that TCP sends a [FIN, ACK] from the side that died to the running task. The running task sends an [ACK] back. Then the side that died sends an [RST] back to the running task, and the running task is notified via normal socket ops that the link has disappeared.

Occasionally when the link has been up for a number of days, when we kill a task we are not seeing any traffic in tcpdump between the two sides. The task that is killed disappears. The link in netstat going to the running task has no client process listed and is in the FIN_WAIT1 state. The link in the other direction from the running task to the killed task is still in ESTABLISHED. The socket layer in the running task is never notified that the link has disappeared.

第二段说的就是kill进程时另一端没有得到FIN通知,从而导致连接残留,至于另一端没有得到FIN通知的原因,在这个案例里是因为防火墙策略,我觉得也不能排除丢包等其他可能。

tcp保活参数,是用下面命令查看:

cd /proc/sys/net/ipv4
cat tcp_keepalive_time
cat tcp_keepalive_intvl
cat tcp_keepalive_probes

三个参数的解释:

tcp_keepalive_time,在TCP保活打开的情况下,最后一次数据交换到TCP发送第一个保活探测包的间隔,即允许的持续空闲时长,或者说每次正常发送心跳的周期,默认值为7200s(2h)。
tcp_keepalive_probes 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认值为9(次)
tcp_keepalive_intvl,在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包的发送频率,默认值为75s。

gearmand上残留垃圾worker问题的解决

我们有时会发现一些worker被kill掉之后,或者某些机器panic了,在gearmand上依然能看到,原因是:gearmand侧因为某种原因未收到FIN通知,而它默认又没开TCP 保活,导致出现残留TCP连接。

我们可用如下选项使能TCP保活,比如下面的例子(案例链接 ):

 /usr/local/sbin/gearmand -p 4732 -L0.0.0.0 --log-file /usr/local/var/log/gearmand1.log --verbose=INFO -w 5 --keepalive --keepalive-idle=60 --keepalive-interval=30 --keepalive-count=3

我们可使用netstat -o选项来查看保活定时器是否生效:

netstat -apno | grep 49539

输出结果为:

tcp        0      0 0.0.0.0:4732            0.0.0.0:*               LISTEN      49539/gearmand       off (0.00/0/0)
tcp        0      0 xx.xx.xx.67:4732      xx.xx.xx.74:39048     ESTABLISHED 49539/gearmand       keepalive (0.80/0/0)

第一行表示gearmand监听在4732端口。第二行表示xx.74有一个worker连接上来,且连接是有keepalive定时器的,keepalive括号里的三列数据,第一列是定时器当前剩余时间,第三列是已重试次数。

我们发现,gearmand和worker之间始终是连接上的(相应的,我们会发现第三列"重试次数"始终为0),说明worker端也在做keepalive。

现在,我们在worker所在的xx.74上把39048端口封掉(可用iptables -D OUTPUT 1恢复)

iptables -A OUTPUT -p tcp --sport 39048 -j DROP

意味着worker不能向gearmand发送报文来维持keepalive了,很快,我们发现netstat -o结果的第三列“重试次数”达到最大值,worker连接被gearmand强制关闭。

再看看gearmand不做keepalive是什么现象,使用如下命令启动gearmand:

/usr/local/sbin/gearmand -p 4732 -L0.0.0.0 --log-file /usr/local/var/log/gearmand_4732.log --verbose=DEBUG -w 5

用netstat命令查出worker端口,接着用iptables命令封掉该端口,结果发现,即使我们把worker停掉,gearmand侧始终还是有这个worker连接,亦即gearmand认为这个连接仍然有效,这样客户端就会挂住!

不过,奇怪的是,如果此时我们新增其它worker进来,gearmand就能察觉到这种“连接残留”现象,把无效连接清理出去,并且后续新增的worker连接都会使用间隔为7200s(系统默认值)的keepalive定时器

如果我们不新增worker连接呢?客户端就会一直挂住。

综上,有几点结论:

  • gearmand默认不启动keepalive,但一旦它发现有“连接残留”现象,会对随后新加入的worker连接起一个默认时长(取决于操作系统的tcp_keepalive_time值,一般是7200s)的keepalive定时器;
  • 为了能够及时发现挂死worker,需要指定gearmand的keepalive参数到一个合适的值;
  • gearman客户端似乎是有keepalive动作的;
  • 使用iptables封端口命令可以模拟出“连接残留”现象。

取消任务

gearadmin --cancel-job <job-handle>  

This can be used to cancel a job that is not currently being handled by a worker. This will not cancel a job which is already in progress (though if the job fails, it will not be run again). 

使用的是gearmand提供的cancel job 管理命令,参考这里

只能取消还在排队的,若已经执行,则无法取消

gearman占用文件句柄数

一个worker连接就会打开一个文件句柄(socket),所以ulimit的限制对gearmand是有效的。

首先查看gearmand的ulimit限制:

cat /proc/32144/limits | grep "Max open files"

结果可能是:

Limit                     Soft Limit           Hard Limit           Units
Max open files            1024                 4096                 files

接着使用

ulimit -a

查看系统限制,结果可能是:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 1028104
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1028104
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

查看open files那一项,为1024,说明每个进程最多只能打开1024个文件句柄。

再看看gearmand占用了多少个文件句柄:

ls -l /proc/34488/fd | wc -l

结果是903.

所以初步怀疑gearmand的卡死跟文件句柄数有关系。调整方法如下,增加-f选项,指定接收的文件句柄数为2048:

/usr/local/sbin/gearmand -d -L0.0.0.0 --log-file /usr/local/var/log/gearmand.log --verbose=INFO -w 5 -f 2048 --keepalive --keepalive-idle=60 --keepalive-interval=30 --keepalive-count=3

顺带说一句,gearmand的文件句柄占用数似乎满足如下的关系:

文件句柄数 > worker总数 + active worker数

所以,worker总数是800,一次批量发送200个任务,就很有可能突破默认的1024的界限。

gearman类似技术

celery:celery是一个分布式的任务调度模块,可以支持多台不同的计算机执行不同的任务或者相同的任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/877053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity每日一记】向量操作摄像机的移动(向量加减)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

【JavaWeb】实训的长篇笔记(上)

JavaWeb的实训是学校的一门课程&#xff0c;老师先讲解一些基础知识&#xff0c;然后让我们自己开发一个比较简单的Web程序。可涉及的知识何其之多&#xff0c;不是实训课的 3 周时间可以讲得完的&#xff0c;只是快速带过。他说&#xff1a;重点是Web开发的流程。 我的实训草草…

c++虚继承(使用)

class A2:virtual public Grand 1.构造顺序按派生列表顺序&#xff0c;若有虚基类先构造虚基类&#xff0c;销毁顺序和构造顺序相反。 2.虚基类时&#xff0c;孙子C来初始化爷爷Grand。 附&#xff1a;thinking in c 2nd https://www.micc.unifi.it/bertini/download/progr…

【数据结构】 初识集合框架

文章目录 什么是集合框架集合框架的重要性开发中的使用笔试及面试题 数据结构是什么容器背后对应的数据结构相关java知识 什么是算法如何学好数据结构以及算法多画图多思考死磕代码多总结多刷题 总结 什么是集合框架 这里博主将简单介绍一下集合框架&#xff0c;想要详细了解的…

为什么需要知识图谱,如何构建它?

从关系数据库迁移到图形数据库的指南 跟随 发表于 迈向数据科学 7 分钟阅读 4天前 154 4 一、说明 TLDR&#xff1a;知识图谱在图数据库中组织事件、人员、资源和文档&#xff0c;以进行高级分析。本文将解释知识图谱的用途&#xff0c;并向您展示如何将关系数据模型转换为图…

【Sklearn】基于最中心分类器算法的数据分类预测(Excel可直接替换数据)

【Sklearn】基于最中心分类器算法的数据分类预测&#xff08;Excel可直接替换数据&#xff09; 1.模型原理2.模型参数3.文件结构4.Excel数据5.下载地址6.完整代码7.运行结果 1.模型原理 最近中心分类器&#xff08;Nearest Centroid Classifier&#xff09;也被称为近似最近邻…

SolidUI 一句话生成任何图形,v0.2.0功能介绍

文章目录 背景聊天窗口提示词 聊天窗口生成输入数据格式柱形图曲面图散点图螺旋线饼图兔子建模地图 设计页面页面布局预览 SolidUI社区的未来规划如何成为贡献者加群 背景 随着文本生成图像的语言模型兴起&#xff0c;SolidUI想帮人们快速构建可视化工具&#xff0c;可视化内容…

BFS(广度优先搜索) 的相关介绍解析

文章目录 DFS 和 BFSBFS 的应用一&#xff1a;层序遍历BFS 的应用二&#xff1a;最短路径最短路径例题讲解 DFS&#xff08;深度优先搜索&#xff09;和 BFS&#xff08;广度优先搜索&#xff09;就像孪生兄弟&#xff0c;提到一个总是想起另一个。然而在实际使用中&#xff0c…

Keburnetes 存储卷 volumes

K8S 的 存储卷 volumes emptyDir 可实现Pod中的容器之间共享目录数据&#xff0c;但emptyDir存储卷没有持久化数据的能力&#xff0c;存储卷会随着Pod生命周期结束而一起删除 &#xff08;一个pod中创建了docker1 docker2两个容器&#xff0c;他们都挂载这个emptyDir&#xff0…

第1期:《实体新零售--瑞幸咖啡》私域爆款案列拆解

朋友们&#xff0c;大家好&#xff0c;阿车写私域相关的内容也有一段时间了&#xff0c;前前后后也接触了不少“私域玩法” “爆款案列”&#xff0c;只是一直不知道怎么分享给大家&#xff0c;前段时间这个分享的想法愈发激烈&#xff0c;所以抽时间好好梳理了一番&#xff0c…

如何初始化Git仓库

如何将目录初始化为Git仓库 一级目录二级目录三级目录 一、准备1、安装 gh2、登录 二、初始化 Git 仓库 一级目录 二级目录 三级目录 一、准备 ​ 在这里&#xff0c;我们需要借助一个非常好用的工具&#xff0c;大家也可以参照官方文档进行阅读&#xff0c;下面介绍常用的…

Java Review - 关于代理的二三事儿

文章目录 Pre概述静态代理概述Code 动态代理概述实现方式一 - JDK代理或接口代理概述Code 实现方式二 - CGLib 子类代理 (Code Generation Library)概述pom依赖Code Pre Java-JDK动态代理 Java-CGLib动态代理 概述 代理模式是一种结构型设计模式&#xff0c;其目的是为其他对…

Windows安装MinGW和简单的使用教程

Windows安装MinGW和简单的使用教程 什么是MinGW&#xff1f; MinGW&#xff0c;是Minimalist GNU for Windows的缩写。它是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合&#xff0c;允许你在GNU/Linux和Windows平台生成本地的Windows程序而不需要…

在P4(Perforce)中使用TortoiseMerge来比较合并

一直习惯于svn的比较合并工具&#xff0c;会觉得p4自带的反人性。还好p4可以在设置里替换成外部的比较合并工具。方法见下图&#xff1a; 1. 比较 2. 合并 注意&#xff0c;如果合并设置有问题&#xff08;某些P4版本&#xff09;&#xff0c;则需要通过一个bat文件来做中转&a…

聊聊看React和Vue的区别

Vue 更适合小项目&#xff0c;React 更适合大公司大项目&#xff1b; Vue 的学习成本较低&#xff0c;很容易上手&#xff0c;但项目质量不能保证...... 真的是这样吗&#xff1f;借助本篇文章&#xff0c;我们来从一些方面的比较来客观的去看这个问题。 论文档的丰富性 从两个…

Linux fork()||fork()问题

以下代码会输出几个"A"&#xff1f; int main() { fork() || fork();printf("A\n");} 代码分析&#xff1a; //父进程fork() || fork();printf("A\n");这里父进程中的第一个fork先执行&#xff0c;产生一个子进程&#xff1a; //子进程…

Electron-builder打包和自动更新

前言 文本主要讲述如何为 electron 打包出来软件配置安装引导和结合 github 的 release 配置自动更新。 electron-builder 是将 Electron 工程打包成相应平台的软件的工具&#xff0c;我的工程是使用 electron-vite 构建的&#xff0c;其默认集成了 electron-builder &#x…

K8S之存储卷

K8S之存储卷 一、emptyDir emptyDir&#xff1a;可实现Pod中的容器之间共享目录数据&#xff0c;但emptyDir存储卷没有持久化数据的能力&#xff0c;存储卷会随着Pod生命周期结束而一起删除二、hostPath hostPath&#xff1a;将Node节点上的目录/文件挂载到Pod容器的指定目录…

【JavaWeb】实训的长篇笔记(下)

文章目录 八、功能实现1、注册功能2、登录功能3、问题说明4、首页数据显示5、后台管理 八、功能实现 1、注册功能 jsp&#xff1a;能够在页面中把数据动态化&#xff0c;jsp和html在元素标签上是无区别的&#xff0c;区别是html中写上java代码就成了jsp文件。filename.jsp。 需…

Threejs学习01——坐标轴展示立方体并实现来回移动

在三维坐标轴上展示立方体并实现来回移动 这是一个非常简单基础的threejs的学习应用&#xff01;创建应用先创建一个场景Scene&#xff0c;然后创建爱你一个透视相机PerspectiveCamera&#xff0c;然后创建立方体BoxGeometry&#xff0c;立方体添加一些材质&#xff0c;将立方…