开源项目 Hello, Faktory

hooopo · 2017年11月24日 · 最后由 lgn21st 回复于 2017年11月24日 · 8054 次阅读

At a high level, Faktory is a work server. It is the repository for background jobs within your application. Jobs have a type and a set of arguments and are placed into queues for workers to fetch and execute.

You can use this server to distribute jobs to one or hundreds of machines. Jobs can be executed with any language by clients using the Faktory API to fetch a job from a queue.

和 Sidekiq 的关系

  • 不依赖 Ruby 和 Redis,使用 Sidekiq 其实就被绑定到了 Ruby 语言上,虽然可以模拟 Sidekiq 的协议从其他语言发送消息让 Sidekiq 处理,但这种方式太 hack,给沟通带来障碍。
  • 支持异构系统,可以用任意语言做生产者和消费者
  • Redis -> Sidekiq == Faktory -> Faktory worker

和其他 Queue 的关系

  • Faktory server(not worker)支持 retry 等特性
  • 提供类似 Sidekiq 的 WebUI
  • 提供类似 Sidekiq 的接口,Ruby 程序员用起来非常熟悉方便

Hello World

Faktory 最大的卖点应该就是支持异构系统,并且保留了从 Sidekiq 积累下的一些好用的特性。下面来实现一个 用 Ruby 做 生产者,Python 做 消费者 的队列:

Ruby client

#!/usr/bin/env ruby
require 'pry'
require 'faktory_worker_ruby'

Faktory.server { |s| s.push(:jobtype => "HelloJob", :jid => "111111111111", :args => [1, 2]) }

Python server

#!/usr/bin/env python
from faktory import Worker

def your_function(x, y):
    print(x + y)

w = Worker(queues=['default'], concurrency=1)
w.register('HelloJob', your_function)

w.run()

当 执行 ruby client 的时候 python server 端会打出 3.

Faktory 的接口格式其实很简单,核心是 queue、jobtype 和 args,相对于 HTTP 协议就是 domain、path 和 body,但相对于 HTTP 的好处其实很多:

  • 比 HTTP 高出几个数量级的可用性
  • 重试处理、失败记录、优先级、用于监控的 WebUI

缺点呢,从目前来说相对不成熟,国内的云服务商短时间内不会提供服务。虽然去掉了 redis 这个依赖,但 redis 已经成了云服务商的标配,然而 faktory server 本身其实需要自己去运维的。

相关链接

看不懂为何要做 Faktory Server 来代替 Redis,增加运维成本,Faktory Server 还需要考虑 HA 的事情。

其实用不同的语言来实现 Queue 的处理器,消息传递用 Redis 或其他相对中立的服务也是可以的呀。

huacnlee 回复

仔细看了一下,Faktory 是内置了 RocksDB 来做消息存储的,RocksDB 在数据可靠性方面应该是比 Redis 好,但是要做 HA 集群的话,就不好说了

numbcoder 回复

RocksDB 跟 Redis 简直没有可比性,数据可靠性方面也都是要看场景。Redis 的特点是内存数据库,速度快,特性丰富,支持通过 Lua 脚本扩展实现事务性提交。RocksDB 是相对于 LevelDB 优化过的 LSM Tree 结构数据库,特别适合海量数据写入场景,但是读性能则很慢。

就 Faktory 项目的定位,以及技术选型,我一度怀疑 Mike Perham 做这个是为了什么,或者我自己没有想明白,反正各种怪怪的感觉。

lgn21st 回复

Redis 的 RDB 和 AOF 两种持久化方式都是有延迟的,也就说如果遇到极端情况,比如突然断电是很有可能丢数据的,而 RocksDB 则没有这个问题。

个人认为 RocksDB 可能比 Redis 更适合这个应用场景,理由:

  1. RocksDB 占用内存更低。虽然读取慢,但既然都是异步任务,应该是不太在乎实时性了。还有就是如果 woker 挂了,大量任务涌进,很有可能导致 Redis 占用内存暴增
  2. RocksDB 数据可靠性更强。Redis 从设计上就没有过多考虑数据的持久化问题
  3. RocksDB 更容易 embedded

其实成熟的消息队列已经很多了,不知道为什么要造轮子,比如 RabbitMQ 等,AMQP 协议各个语言都有实现,轻松跨语言做 worker

我感觉 Mike Perham 在不断试错吧,Ruby sidekiq 成功后,现在一直不断寻找新的突破口。他也在不断的折腾: crystal 版本的 sidekiq, golang 实现的 inspeqtor 再到现在 golang 实现的 faktory.

虽然现在也不太愿意使用 faktory, 但在已经稳定的 一个人的公司 仍然这样不断创新也挺佩服。

另外,对于不同系统之间的异构系统,也有太多方案可选择了。比如复杂一点就上 RabbitMQ 了。

numbcoder 回复

个人觉得比 RocksDB 适合拿来做消息队列的技术选型多了去了,也是不明白为什么要造轮子。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号