基于 rails guides,自己打造了一下 https://github.com/dengqinghua/roses
评论用的 gitalk
最终生成静态页面,服务部署在 github pages 中,再在域名上面配置 cname
博客经过打造后,支持 流程图,树结构,五线谱和吉他和弦 😀
请教一个问题,既然尾递归可以 一定程度
上解决递归导致的内存泄漏问题,为什么这个参数没有默认开启呢?尾递归的开销是什么呢?
明白了,谢谢楼主分享。
一致性哈希算法
很赞,学习了新的知识,非常感谢!
在 Ruby 中 some_hash[some_key] = some_value 这种哈希操作虽然有多个步骤(取哈希值=>做映射=>再赋值),但整个操作在底层是由 C 语言实现的,而 GIL 会保证这段 C 代码执行的原子性。这里面并没有真正的并发。
楼主您好,请问这块有源码分析吗?您说的 GIL,只是用不到多核而已,并发并不是指用到了多核才是并发。
ruby 的并发同样涉及到上下文切换,所以并发中的竞争问题(race condition)同样存在的。
GIL 不意味着 线程安全
建议可以看下 working with ruby threads 第五章的内容
感谢分享,我们会参考一下。
我们在设计的时候会考虑几点:
1. Sidekiq Worker不需要去管理job的状态, 也就是并发的任务本身对job状态是无感知的, 也没有状态的概念
2. 工具是通用的, 不仅仅在导出场景, 任何批量多任务处理, 都可以使用.
在新版本的 Rails 中,有 ActiveJob, 里面的 callback 可以做到这些功能,但是我们并未在上面做扩展,因为
您说的这个也是一个解决方案,但是个人觉得太偏向于某一种场景了,如果换一种场景的话,可能又得再实现一遍; 建议可以抽离出一个插件,做成一个执行引擎,相信从可读性和实用性而言会更好一些。
嗯,是的。
这个文档解决的问题,是希望耗时的任务 高性能并且状态可跟踪, 跟高可用关系不大,所以没有考虑自己实现 RPOPLPUSH
是的,您说得对。
但是这一块是专门为 sidekiq 定制的,数据结构设计还包括 sidekiq_class 等,这些其实也可以用在 kafka 中。
Pro 版本使用到了,用来做高可用,保证数据不丢的。
Sidekiq Pro offers an alternative fetch strategy, super_fetch, for job processing using Redis' RPOPLPUSH command which keeps jobs in Redis.
wiki: 这里
是的,我们是这样做的。
job_id 在执行
job_id = AWorker.perform_async(params)
的时候,已经生成了。但是需要利用 Sidekiq 的 Middleware, 去更新这个 job 的执行情况。
对于前端,只需要轮询状态就可以了。
each_slice
这块我理解得不对,我们在实际业务的做法跟您所说的是一致的。
因为我们需要一个 job 的状态,以及业务失败时,这个 job 的错误信息。
如下面的信息:
{ status: failed, message: "发生错误: 您的资质不满足报名条件" }
我们是通过 raise NormalException
来中断任务,并将信息存储在异常中的。
所以说,我们需要通过 job_id, 来找到这个 job, 访问这个 job 的状态 (status
), 并拿到业务逻辑的错误信息 (message
)
这儿其实跟 Erlang 的 Let It Crash
有点儿像,但是使用上会稍微简单一点。
另外,所有跟 job 相关的参数,状态信息也都会入到数据库。因为 Sidekiq 的 任务是使用 Redis#brpop
命令的,消费了之后,消息就没有了,就找不到这个 job 了。
我的理解如下:
def push_bulk(items)
...
raw_push(payloads) if !payloads.empty?
# 如果有十万个任务, 这里需要循环十万次得到jid
payloads.collect { |payload| payload['jid'] }
end
我们部署 Sidekiq 多个进程,就有一定概率使用到多核。
50 万数据我们是分成多个 sidekiq job 处理,并且有一个 task_id 跟这些 job 关联。这样可以用到了多核,也能观察到各个任务进行的进度,并且可以重试.
当然单独针对这个业务逻辑,也可以设计单独的表结构来存储任务。
嗯,可以贴一下链接或者设计思路吗?我们也都学习一下。
这些其实都是造轮子,我们的痛点是一些资源申请不下来。
非常赞!
楼主可以对比一下 Sidekiq 和 Kafka 或者其他的队列吗?如 Sidekiq 是怎么做到 客户端 和 服务端的高可用的呢?
楼主很棒,感谢分享!
希望楼主也能分析一下 sidekiq 中 线程的监控,以及 sidekiq 由原来的 Celluloid 换成 Raw Threads 的方式后,线程之间的通信情况。
还有一些队列的基本问题:如 为什么 Sidekiq 是 At Least Once 等,我们能做到 Exactly Once 吗
等等之类的问题。
可以拿到 job 情况。但是在 sidekiq 的存储结构中,并没有将 job_id 当做 key 来存储
通过 sidekiq 的 api 获取 job 是非常低效的,在 API 文档 中提到
Find a job by JID (WARNING: this is very inefficient if your queue is big!)
另外,我们需要获取到 job 的整个状态,包括 进入队列,处理中,成功,业务校验的失败,系统的失败 等,这是 sidekiq 的 api 不具备的。
sidekiq-pro 提供了类似 batches 功能,但是我们因为一些原因没有使用。