这是第一次实现流处理基础设施而我的毒药是storm 1.0.1, kafka 0.9.0和Clojure 1.5。
现在我有使用消息传递系统(RabbitMQ)的背景,我喜欢它有几个原因。
然而,它无法达到我想要的吞吐量。
现在经历了Kafka,它在很大程度上取决于手动维护偏移(在Kafka经纪人内部,Zookeper或外部)
我终于设法在Clojure创造了一个鲸鱼喷水源,其源头是Kafka经纪人,这是噩梦。
现在,对于大多数场景来说,我想要的是“完全一次消息传递”,并且根据Kafka documentation州
因此,Kafka保证默认情况下至少一次交付,并允许用户通过禁用生产者的重试并在处理一批消息之前提交其偏移量,最多实施一次交付。完全一次交付需要与目标存储系统合作,但Kafka提供的偏移使得直接实现这一点。
这对于一个clojure kafka鲸鱼嘴来说意味着什么,发现很难概念化。
我可能沿途有几个boltz,但终点是Postgres集群。我要将偏移量存储在数据库中(听起来像等待发生的种族危险),并且在我的风暴群集的初始化中,我从Postgres获取偏移量?
还有将Kafka喷口的平行度设置为大于1的数字的危险吗?
我通常使用this作为起点,因为很多事情的例子在Clojure中都没有。对我正在使用的版本进行一些小调整。 (我的信息并不像我期望的那样出来,但至少我能看到它们)
(def ^{:private true
:doc "kafka spout config definition"}
spout-config (let [cfg (SpoutConfig. (ZkHosts. "127.0.0.1:2181") "test" "/broker" (.toString (UUID/randomUUID)))]
;;(set! (. cfg scheme) (StringScheme.)) depricated
(set! (. cfg scheme) (SchemeAsMultiScheme. (StringScheme.)))
;;(.forceStartOffsetTime cfg -2)
cfg))
(defn mk-topology []
(topology
{;;"1" (spout-spec sentence-spout)
"1" (spout-spec my-kafka-spout :p 1)
"2" (spout-spec (sentence-spout-parameterized
["the cat jumped over the door"
"greetings from a faraway land"])
:p 2)}
{"3" (bolt-spec {"1" :shuffle}
split-sentence
:p 5)
"4" (bolt-spec {"3" ["word"]}
word-count
:p 1)}))
答案 0 :(得分:1)
对于任何分布式系统,都无法确保要完成的部分工作只能完成一次。在某些时候某些东西会失败,它将需要重试(这称为"至少一次"处理)或不重试(这称为"最多一次"处理)尽管你可以& #39; t恰好位于其中间,并且恰好一次"处理。你能得到的是非常接近一次处理。
诀窍是,在您的过程结束时,如果您发现该工作已完成两次,则抛出第二个副本。这是索引进入的位置。当您将结果保存到数据库中时,查看是否已保存使用比此工作索引更晚的索引的工作。如果您发现此后续工作存在,则将工作抛出并且不要保存。至于文档,这是那种只有" strait forward"对那些多次做过的人......