普通视图

发现新文章,点击刷新页面。
昨天 — 2024年10月15日首页

司徒雷登在华五十年

作者 陈大猫
2024年10月15日 17:20

司徒雷登在华五十年
和很多人一样,知道“司徒雷登”这四个字来源于毛主席的那篇《别了,司徒雷登》。

除此之外,对司徒雷登这个人,我们知之甚少。

前不久,我偶然读到一篇关于当年燕京大学筹建选址的文章,里面提到司徒雷登为了争取一个风景极佳的的地块作为校园,亲自找到陕西督军陈树藩,商量购买事宜。这块地本是陈树藩的父亲打算用来建祠堂的,断不可出售。结果陈树藩不仅应允,而且以极低的价格转让,成为美谈。

看完这篇文章,让我对司徒雷登这个既熟悉又陌生的人产生了兴趣。究竟他是一个什么样的人,能让毛主席亲自写一篇指名道姓的文章?他与中国的渊源如何?

这些问题在司徒雷登的自传《在华五十年》里都有详细的解答。

所以,我就从孔夫子旧书网购买了一本,前后花了两周时间读完,现在写篇简单的读后感。

司徒雷登的一生,历经多个角色:传教士的儿子、传教士、教育家、外交官。

作为传教士的儿子,他很自然的出生在了中国,从此一生与中国结缘。然而他的主要求学经历又是在美国,这就注定了他的思维方式、价值取向、行为习惯,所有的一切都准确无误的表明:司徒雷登是一个美国人。

作为传教士,他也是合格的。实事求是地说,明清时期的传教士为旧社会中国带来了科学技术和民主观念,是值得肯定的。在传教过程中,他深入民间,体察民情,深感这个国家的落后与愚昧,也切切实实希望通过一番作为改变现状。

作为教育家,这是他的人生高光时刻,也是他最引以为豪的身份。参与创办燕京大学,并长期担任校务长,让他在华传教事业上升了不止一个高度。凭借传教士的身份,他身体力行四处筹款,使得燕京大学在当时有实力成为全国最好的高校之一。充足的经费,优秀的教师队伍,完善的设备,美丽的环境,培养了一大批具有先进理念的知识分子,成为那个年代救亡图存的一支重要有生力量。

作为外交官,他无疑是非常沮丧的。关于司徒雷登担任美国驻华大使的那一段经历,可以说是全书最为精彩的部分,他从另一个视角描述了解放战争前夕国共两党的激烈斗争。很可惜,司徒雷登站错了队伍,虽然他跟很多中共官员有不错的私交,但自始至终他都坚定不移和蒋介石及国民党站在一起,维护他们的利益。这也就是为什么毛主席会写那篇著名的文章,因为司徒雷登的确是美帝国主义在中国的执行者和代言人。那个时代,国民党是中华民国政权的执政者,是受国际认可的官方。二战后,中华民国与同盟国平起平坐,参与战后秩序的维护,接受美国的大量资助。美国希望扶持国民党政权,建设一个和平繁荣的中国。但关键在于彼时国民党虽然坐在正统的位置,但已然腐朽到极致,就连司徒雷登都看到了问题的所在,但积重难返,无法破解。最终,蒋介石丢失了政权,仓皇逃跑至台湾。

司徒雷登和蒋介石私交非常好,这不仅是因为工作的缘故,还因为蒋介石本身就是一个基督徒。

所以,当蒋介石溃败后,司徒雷登的结局是可想而知的。

2008年11月17日,司徒雷登的骨灰远涉重洋被带到了杭州,他的出生地,安葬于半山安贤园文星苑。虽然没能实现他葬在燕京大学的遗愿,但能回到中国,也算是为他一生划上完整的句号。

 

昨天以前首页

读书小结五

作者 Juby
2024年9月30日 22:33

锌皮娃娃兵

  • 入侵阿富汗的战争让苏联陷入泥淖,是其衰落和解体的重要原因之一,然而在我们的历史教科书上却没有对这场战争的描述。
  • 他们怀着成为英雄或为国效力的理想奔赴战场,却成为这场不义战争中的施害者和受害者,要么身体的碎片被装进棺材,要么被视为犯下暴行的罪人回到祖国。

人慈:橫跨二十萬年的人性旅程,用更好的視角看待自己

  • 将humankind译为人慈,既为该词的拆解式直译,又可切题,还谐音“仁慈”,当赞为妙笔。
  • 作者为了宣扬“人性本善”,似乎走入了另一个极端,要彻底否认“人性本恶”。他立了几个典型的靶子——戈尔丁的《蝇王》、复活节岛的故事、霍布斯的《利维坦》以及几个经典的心理学实验(斯坦福监狱实验、电击实验、旁观者效应、破窗理论等)——然后再用个别案例和他人研究把这些靶子一一打倒。然而,作者列出的论据却并不是那么有说服力,而是陷入了以具体否定抽象的奇怪驳论境地。
  • 为了否定《蝇王》,作者费劲千辛万苦在现实世界中找到了一个类似小说处境的真实故事,然后就说《蝇王》的故事在真实世界是不会出现的,只是戈尔丁恶意的想象,甚至以攻击戈尔丁的人格来证明自己的论点。对人性的解释难道也是数理逻辑吗,以一个反例驳倒一个命题。
  • 复活节岛的历史研究是错误的,心理学实验是动了手脚和无良媒体推波助澜传播的。至于那些精心挑选的展现人类的和善、仁慈、友爱、宽恕和团结的动人故事,也可以有别的解释。这差不多就是作者的全部论据了。为什么有那么多证明“人性恶”的实验却少有证明“人性善”的实验呢?
  • 作者想要宣扬“人性善”并没有问题,但为什么让全面否定“人性恶”的看法吗,妄图以一种宗教取代另一种宗教?当所有人都成了”人性善”教的教徒,世界就会充满爱与和平吗?
  • 我不相信人性善,也不相信人性恶,我觉得先天的人性是空白的,是被后天的环境和教育染上了各种颜色。
  • 这本书可以结合《人性实验》一起阅读,后者有前者所反驳的所有实验的介绍。

祈祷之海

  • 讨论哲学、人性、自我和宗教的科幻小说。
  • 科技和医学的进步会湮灭人性吗?
  • 一种有趣的未来科技(能够取代人类大脑的宝石——恩多利装置)可见于不同的故事。
  • 祈祷之海,是“我”从神的安慰中觉醒的故事。

白鳥の逃亡者

  • 女主角是拉cello的天才高中少女,和已婚的指挥家有婚外情;男主角是杀死了妻子和她出轨对象的普通上班族。两人在车站的一次意外相撞,却演绎出了一段彼此安慰和救赎的故事。
  • 无聊的小说,学日语的读物。

蝇王

  • 事先知道了这是一个影响深远的故事,反而没有带来什么震撼。
  • 译文佶屈聱牙,小说本身也有很多刻意的描写,读起来像是一部十八世纪或十九世纪早期的作品,不是很喜欢。
  • 最后一章,拉尔夫逃避杰克一群人的追杀时,很有代入感,不自觉地让人紧张起来,为他捏一把汗。

好像老花了

作者 xrspook
2024年9月28日 10:37

当年今日

某天,跟往常一样,我半躺着在家里的床上,戴着近视眼镜,拿了一个药盒之类的东西放在眼前,突然发现我什么都看不到,一片模糊。当我把眼镜拿开好像又能看到了,但是当我把东西更加靠近眼睛,又一片模糊。那一刻我才知道,原来近视眼镜是有盲点的。那个盲点对我来说,大概是离眼睛20厘米以内的地方,摘掉近视眼镜之后,盲点会缩短,大概在10厘米以内。

以前我觉得看药瓶上的说明是很简单的事,但现在我觉得那对我来说变得困难了,尤其是在光线不好的地方,无论我用什么样的距离,我都看不清。戴着近视眼镜看不清,不戴近视眼镜也看不清。光线好一点的时候,可能会看清,但是得比较用力看。因为数据比较多,又不得不在一页A4纸里把东西都打印出来,所以也就只能用缩小的功能。缩小的那些字体大概只有正常大小的1/4。就字体的大小来说,肯定要比药盒或者药瓶上面的字体大,但是激光打印机加普通的A4纸出来的效果肯定不如专业的印刷。遇到那些纸质表格,我也得非常努力才能看清上面的字,前提是我有点知道那到底是什么。

我才38岁而已,但我不得不接受一个事实,估计我已经有老花了。我小学四年级开始就已经有了近视,一开始的时候没有散光,后来连散光都有了,现在的我近视老花散光,再加上长期在阳光底下不做任何防护,所以估计白内障也是有的。

老花这个东西是我近期感觉到了。所以当同事把我们共享的表格缩小使用的时候我就得看得很用力,之所以她们得缩小使用,是因为她们在笔记本上操作。高端的笔记本分辨率很高,但是太高的分辨率,字体虽然是清晰的,但是你却看得很辛苦,所以不得不放大。比较老的笔记本属于那种分辨率就那个样了,所以即便用到100%的分辨率,屏幕显示的东西还是不够多,于是她们同样的操作就是把Excel表格缩小显示。我不用干这种事情,因为我尽可能不在笔记本上操作。操作的电脑都是台式机。绝大多数情况下,会在办公室的台式机又或者是我家里的台式机里完成。两个台式机配套的那个显示器要分辨率和显示效果基本上完全一致。这不是什么巧合,是我觉得单位的那个我用得很舒服,所以依照那个款式家里那个尽可能买同款,全自费。

从前我觉得老花这种事情,老人家才有,我觉得我自己的这个年龄,无论如何也称不上是老人,甚至有些中年人也不认同我踏入了他们的俱乐部,但事实就是这么残忍。之所以会发生这种事,是因为过去这些年,我们过度地在电子产品上消耗我们的眼睛,所以我们跟老一辈的人相比,眼睛的老化速度比他们快起码15年。

我可以怎么办呢?当我连很普通的正常大小字体也看不清的时候,大概我也就只能去配老花镜了,然后就是一天到晚不停地更换眼镜。

如果风知道

作者 ONO
2024年9月28日 14:00

我经常听人说话,别人付钱让我们听的,或是我们付钱听别人的,亦或是亲密关系里必要的“交谈”部分。所以久而久之,我会在大脑里出现一个习惯性的“系统”,在对方说话的时候,会把对方的每一句话自动归类到不同的信息之中——哪些是有效的、哪些是谎言、哪些有后期加工的成分、哪些是技巧、哪些是真实的感受、哪些是理性、哪些又是感性……

分类的好处,是我可以保持大脑低功耗的方式,处理大量的无效信息。因为很多时候,人们在谈及感受的时候,会本能地忽略理性思考的部分,以至于他们讲述的内容会分崩离析,只有这种方式才能快速地从对方的话语中找到关键点。


因此,别人付钱让我们听说话的,才真的可以做到完全信息同步的方式处理对方提供的大量无效信息。能在生命中遇到一个理性的聊天对象,本就不是容易的事情,更何况还需要同频彼此的认知,将讨论的事情放在一个框架下进行逻辑推理。

没错,上面这段话是在“装逼”。简单来说就是,我们至少得从一个事件里面找到前因后果,然后理解它发生的原因以及面对问题时的解决方案。我极少会提供解决方案,因为我知道大部分人并不愿意知道解决方案,他们需要的是事件存在时的拉扯感。

举个例子,很多人抱怨原生家庭自己的父母如何对自己“残忍”,其实我们有很多解决方案。把这种源源不断的恨付诸行动,比如断开原生家庭提供的经济支持,甚至是把聆听者当作“父母”,狠狠地抽对方一耳光将这种恨意实体化。但绝大部分的人是做不到这一点的,因为这种仇恨本身就是证明自己还活着的存在感——这种拉扯感的情绪既可以让自己拥有“埋怨”的权利,也可以为自己的“作”找到最终解释权,更重要的是,这种深切的痛即是“活着”

从对方的描述中找到问题根源、甚至挖掘到当事人自己也不愿意面对的真相,这是我的能力,但极少有人希望得到解决方案——或者他们觉得这件事没必要解决(然后被伪装成“我觉得这件事解决不了”)。这么一段时间来,我只遇到一个主动向我提出“你先别给我解决方案”的人,就是之前提到的那个3P男孩——这个人的故事以后再聊。他拒绝我提供解决方案的原因是他觉得“这是他必须要去体验的过程”。


在这么多“聊天”之中,我找到了某种有趣的现象——从事件本身聊到问题根源,直到最后得到解决方案。“解决问题途径”看上去是一套正常的“流程”,除了刚才讲到很多人不愿意得到解决方案的情形以外,找到问题根源本身也不是件容易事。因为它需要大量的真实信息呈现和同步,甚至还需要当事人对其“真实性”进行质疑和深入讨论。很多人面对一般的否定都难以承受,更别说还要接受他人对自己“真实性”的评价——但之前我提到过,人们对于记忆的篡改是一种心理本能,要对这些记忆的真实性拆解时,本身就会涉及对一个人心理动机的深挖,甚至会让当事人看见未曾见过的真实自己。

于是,从事件到问题根源的“发现问题途径”也变得不那么“友善”,所以人们开始寻求第三种更加轻松的路径——希望通过用一句结论的方式覆盖一个繁杂问题-解决方案体系,我把这种路径取名为“摘要途径”。

摘要途径往往会有一句非常简单明了的话,覆盖一个庞大的逻辑推理过程——例如“男人就是犯贱”。看上去这个结论可以覆盖很多男性的行为,但仅以此来评价男性行为很难说服“我这类人”。比如我花了一整个《性癖纵横观》的篇幅,来解释“男人就是犯贱”这个结论。性癖反馈男性的心理需求,征服与被征服作为能量转换,男性有的时候需要被征服的方式来平衡心理,于是对于被征服的性需求转变成了符号,而丝袜高跟鞋就是符号之一,所以被高跟鞋踩踏生殖器看上去是一个“下贱”的需求,但它背后有一些整个完整的逻辑推理。

当然,这个推理也并不是所有人关心的。


“摘要途径”不仅可以省略复杂的推理过程,也可以规避一些原本不属于自己强项的知识领域,可以让自己轻松地跟那些知识领域强者“平起平坐”——你说的这个理论我懂,不就是男人都是犯贱的嘛。你看,有了“摘要途径”,似乎就得到了一个知识领域的捷径,可以直接得到立马能用起来的结论。

前几天我无聊翻到一本书《风吹哪页读哪页》。本着对这本书标题的尊重,我真的就随便翻了一页读起来。里面的内容很庞杂,但是又非常简单——它在里面收集了从古至今的名言警句,通过分类成不同人生状态、阶段的方式装订成册。每一个摘要都在一眼就能读完的篇幅之中,能够用最短的方式理解“事物的本质”。它很像心灵鸡汤,但又不全是,因为里面的句子还是很值得深入琢磨,或是因为今天的有感而发而换做了微信签名,跟换头像明志有着一样的作用。

这本书就是非常典型的“摘要途径”,人们在追求的是一种结论上的支持,比如我今天想要出轨,我总得有一个支持出轨行为的声音在背后推我一把。如果这个人是具有权威性的,那我出轨的想法就可以得到古今中外的“担责”。“摘要途径”最大的特点是当事人并未参与其中——如果这个结论是“身边人”提供的,很有可能会在最后东窗事发时,一句“这可是你让我去做的”而把所有责任都推卸出去。因为“发现问题途径”本身,是需要当事人扪心自问,发现自己的“问题”,当事人在参与其中时,如果一味地外归因虽然“没有错”,但是至少对帮助的人来说,这种强烈的外归因行为会让他们失去解决问题的机会,而恰好“摘要途径”就是这个完美的“外归因”。


如果真就跟《风吹哪页读哪页》一样,风能帮你带来所有事情的“摘要”,那人也不至于活得这么痛苦了——这种痛苦不是源自于解决不了问题,而是当我们看了这么多“摘要”之后,人生还可以过得一塌糊涂。这种似懂非懂的信息越多,只会让我们麻痹在无数的结论之中,却放弃了“生而为人”的体验。

否则那些灵修课还怎么赚钱呢~

2024 七月读宇宙,易经,博伽梵歌,觉醒,认知行为疗法,哲学…… 10 本

2024年9月6日 17:23
宇宙是时空,而Universe代表合一。时间与空间的区别的确也在宇宙学中已经消弭。 学到的东西,若从知见转变为体悟,便多一分清明。体悟是修行的路。 CBT中这么多方法,改变认知入手的,改变行为入手的。凡是最后起作用的,都是帮助来访者获得体悟的。 CBT也是修行。

AI巴别塔与信息焦虑 II

作者 ONO
2024年9月4日 16:07

借助AI,人类能够创造出更多超越认知的作品?还是因为其便利性可以制造越来越多不经审查的“垃圾”?

这并不是一个短期只能可以看到结果的事情,AI时代才刚刚开始,而人类是否会被取代,目前我们还停留在“凡人类制造的,人类只需要保留最后拔掉插头的权力即可”,就是对人工智能最后一层自信。

前些日子,我在Instagram刷到诸如此类的广告:全程翻译外国语大学教授的课堂内容,或是将一篇长达10万字的论文导入AI由他精简其内容,或是将一个长达1小时的演讲导入AI由他总结出只需要5分钟就能看懂的文字版——当然,5分钟的阅读时间,对于这个信息爆炸的时代而言还是太长。所以人们在标注“全文阅读时间”的同时,都倾向于在文章的最开始,整理出3行字就能“理解全文”的重要内容。

那为什么还要创作一本书、一篇文章或是一大段的文字——是不是任何信息都可以变成3行字,以便满足所谓的“适读性”?

——Previously on AI巴别塔与信息焦虑

我认识一个“创作者”,他至今对ChatGPT都充满了“恐惧”。恐惧的底层是对“未知”没有掌控感,那到底AI的“未知”在哪里——如果你是一个常用AI辅助工作的人,就会很快发现它的局限性——它很难做到真正溯源。所以真的要严谨地完成论据-结论的工作,仍然需要人类作为审查机制。

如果要用“我知道更多知识”作为一个评判标准,那人类在AI面前几乎就是沙漠里的一粒沙——我们假设一个人可以活到80岁,从10岁开始阅读书籍,每年平均阅读50本书,那么这个人类这一生也只能读完3500本书。现阶段,人类已经创作的书籍粗略估计早已经超过上亿本。3500之于100000000,已经显得微不足道,更何况在书籍之外,互联网的兴起让这个数值变得更多,出现了奇点式的增长。更何况很多人一年也读不了50本书……活不活得到80岁再说,毕竟65岁才能退休呢。

再说全科知识,人类更难做到每一个学科都可以深入学习。因此两点,人类在AI面前一败涂地。既然如此,那我们就得换一个思路去理解AI,如果它是一个超级存储器,可以记录全科百科,甚至是世界上已经存在的上亿本书籍。那我们或许可以用它做一件事:把这一亿本书每一本都提炼出300字的观点或中心思想,按照人类平均每分钟阅读200字的能力,不吃不喝不睡觉地读完这一亿本书的摘要,也需要285.7年的时间。

当然,这些数值并不是“确信值”,但这个极限值确实存在,现代社会我们能接受的信息远超过这个“极限压力”的数值。


今年上半年,我一直处于某种可以被感知的“焦虑”之中,但这种焦虑区别于死亡焦虑的目的性,它几乎找不到原因。这两天我也在朋友圈总结过:

今年整整5个月,我都处于一种“慢性焦虑”之中,所谓慢性焦虑就是不实质影响生活,但又能够明显感知。和之前死亡焦虑不同,我都不知道它源头在哪儿。

精准的分割线就是从香港看完苏打绿的演唱会之后(因为从朋友圈发布质量看出来的),在香港观察城市和人的时候,脑子调取了《制造宠物》这本书,然后牵扯出了我高中时上课无聊看各种故事解构的“课外书”,再到帮北影的毕业生写关于“城市构建与毁灭”的毕业论文。我发现我有很多零散的信息开始大量地出现在脑子里,不同跨度的事件被一瞬间callback。然后那个时候脑子“乱”了。

我为了对抗这种慢性焦虑,继续找书看、把思绪绕在主轴上的坚持写作也没有停、健身、体检报告也OK、狗造成的催产素也仅仅影响情绪。于是看-输出-看-输出就成了吗啡一样,麻木接受的信息越来越杂,其中掺杂着大量AI杜撰的垃圾文,又得花大量时间溯源,为了突破信息茧房“什么都看看”,输入的东西越来越多,不想错过的信息也越来越多——于是,信息焦虑的构成要件全都齐了。


信息大量出现,甚至有越来越多不经验证和溯源的信息出现;

信息间的联系因为信息茧房出现非关联性,从物理上被作了切断。这一点不得不承认,抖音更像是一个“佛教用品”,它的每一个信息都是独立的,短暂而丰富,因为一条信息开始需要思考“为什么”的时候,下一条信息出现,切断了上一条信息可能带来的“执念”——它确实像是一种“放下执念”的训练工具。

我虽然很厌烦APP的提醒功能,但有些软件我会打开提醒,例如微信、RSS订阅软件、博客评论提醒功能。我已经尽量地做到了“免打扰”,但是每次打开APP,都可以看到铺天盖地的未读红点。我一直以为自己是因为强迫症需要去确认这些红点,后来才意识到,这种强迫性行为,是因为“不想错过信息”导致的。

我细数了一下,可以作为信息来源的社交软件、信息订阅软件竟然有13个,他们分成被动提醒和主动索取两种,但无论哪种,我就得在这个电子产品上花费更多时间。信息来源越多,就意味着我的注意力会被分散得更多。虽然我对信息并不上瘾,但当信息过载积压时,我会觉得我需要花更多时间和精力去处理这些“被错过”的信息。

于是,这四个点共同构成了信息焦虑的关键原因——信息过载、信息茧房、不愿意错过信息和精力被过度分散。一旦出现信息焦虑,就会疯狂地寻找更多的信息以满足焦虑感,但事实上这个时候接收信息会因为杂乱而变得更加无序。过量获取的信息因为混乱无序而在内部形成“熵增”情形,只会导致越来越多原本有序的信息也跟着错乱,直到引发全面的精神焦虑。


当人们面对信息焦虑时,能想到的,无非是切断信息源,冷静一段时间;或是继续找寻下一个更加“优质”的信息源——这两者都是滞后性的商业模式;前者是提供替代焦虑的各种认知倾向,例如利用化学药剂的倾向,为焦虑者提供更多的酒精、药品或叶子;也可以利用能量平衡的方式,为输入焦虑的人提供能量输出的平衡——比如参加可以评判别人甚至是释放负面情绪的活动;后者,也是现在很多人在利用AI做的工作,例如将一本书、一部电影通过AI变成“捷径”,让人花最少的时间去对抗必须亲自读完书或看完电影的时间。

很显然,这两个方向并不能根治信息焦虑,反而会制造更多的求知缺口,让自己变得更加麻木。

当知识占满了整个认知空间时,对外对己的感应被切断时,一个人距离抑郁也不会太远了,这个话题下一期再聊。

读书小结四

作者 Juby
2024年9月1日 10:16

大地上我们转瞬即逝的迅绚烂,是一本写给母亲的书,是一本自传。作者是越南移民,由母亲和外祖母抚养长大,书中带着歉意和爱意回忆着与母亲过往生活的点滴细节。为养家而被工作摧毁健康的母亲和她那对儿子时常带着粗暴的爱,体现出移民家庭在美国的生活之艰辛。外祖母对越南战争的回忆,提醒人们战争的伤痕永远无法消除。除了移民和越战元素,这本书也塑造了母亲和外祖母这两位勇敢而坚强的女性形象。

吉尔伽美什史诗,一部苏美尔英雄史诗,讲述了古代的王吉尔伽美什因好友恩启都遽死而意欲追求永生,历经千难万险却无功而返的故事。史诗中有大洪水的情节,应该是圣经大洪水的原版故事之一吧。

时代的喧嚣,是曼德施塔姆的自传、文论和书信的合集。自传讲述的重点不在自己,而是当时的社会环境和氛围,给人一种醉生梦死、穷奢极乐、风雨欲来的感觉。

重返天安門,是个人与六四的故事,有参与镇压的士兵,有受害者的母亲,有运动的学生领袖(离开的和留下的),也有未曾亲历的年轻一代。最后,还讲述了不为人知的成都屠杀事件。

青年变革者,是写梁启超的,通篇引用,看似旁征博引,实则枯燥至极。此书一点生气没有,一点己见没有,一点梁启超的魅力亦没有。烂书勿读。

死亡是一件孤独的事,装神弄鬼、莫名其妙的小说,除了名字一无是处。不要在这本书上浪费哪怕一分钟的时间,以我浪费了几个小时的经验之谈。

从参与 Rust 标准库开发看开源贡献的源动力

作者 tison
2024年8月9日 08:00

首先介绍一下我在 Rust 标准库当中做的两个微小的工作。

第一个是从去年 8 月 14 日发起,今年 4 月 6 日合并,历时约 8 个月,目前仍在等待 stabilize 的为 OnceCellOnceLock 增加新接口的提案:

第一次提交贡献

第一次贡献成功合并后,马上第二个工作是从今年 4 月 8 号开始,7 月 6 号合并,历时约 3 个月,同样还在等待 stabilize 的为 PathBufPath 增加拼接扩展名新接口的提案:

第二次提交贡献

可以看到,这两次贡献的内容可算是同种类型的,第二次提交从发起到合并的时间比第一次缩短了一半以上。本文先介绍 Rust 标准库提案的基本工作流程,然后介绍这两个贡献背后的故事,最终讨论开源贡献的源动力从何而来。

Rust 标准库提案的工作流程

标准库的贡献有很多种,上面我所做的两个贡献都是扩充现有数据结构的接口,也就是 API Change 类型的提案。

Rust 社群为 API Change Proposal (ACP) 设计了专门的流程,流程文档记录在 std-dev-guide 手册中。

简单来说,一共分为以下三个步骤:

  1. rust-lang/libs-team 仓库中创建一个新的 ACP 类型的 Issue 开始讨论;
  2. 讨论形成初步共识以后,修改 rust-lang/rust 仓库中标准库的代码并提交 PR 开始评审;
  3. 针对实现达成共识以后,在 rust-lang/rust 仓库中创建对应的 Tracking Issue 并由此获得标注 unstable feature 需要的参数(Issue 编码);PR 合并后,由 Tracking Issue 记录后续的 stabilize 流程

不过,其实我所做的两个简单改动并没有严格遵循这个流程。因为我首先不知道这个流程,加上实际改动的代码非常少,我是直接一个 PR 打上去,然后问一句:“老板们,这里流程是啥?我这有个代码补丁还不错,你看咋进去合适。”

开源贡献的源动力从何而来

为什么要给 OnceCell 和 OnceLock 加接口?

真要说起来,给 OnceCell 和 OnceLock 加接口的起点,还真不是直接一个 PR 怼脸。上面 PR 截图里也能看到,首先是我在原先加入 once_cell 功能的 Tracking Issue 提出为何没有加这两个接口的问题:


进一步地,之所以会提出这个问题,是我当时在实现 Apache Kafka API 当中 RecordBatch 接口,其中涉及到一个解码后缓存结果的优化。因为 Rust 对所有权和可变性的各种检查和契约,如果想用 OnceCell 来实现仅解码(初始化)一次的效果,又想要在特定上下文里取得一个可变引用,那就需要一个 get_mut_or_init 语义的接口。

实际上,这个接口的实现跟现有的 get_or_init 逻辑几乎一致,除了在接收者参数和结果都会加上 &mut 修饰符以外,没有区别。所以我倾向于认为是一开始加的时候没有具体的需求,就没立刻加上,而不是设计上有什么特殊的考量。

于是,开始讨论后的下一周,我就提交了实现功能的代码补丁。很快有一位志愿者告诉我应该到 rust-lang/libs-team 仓库走 ACP 的流程,我读了一下文档,尝试跟提出这个要求的志愿者 confirm 一下具体的动作。不过马上就是两个多月的毫无响应,我也就把这件事情暂时搁置了。

经典开始等待……

11 月,两位 Rust 语言的团队成员过问这个补丁。尤其是我看到 Rust 社群著名的大魔法师 @dtolnay 表示这个补丁确实有用,应该合进去以后,我感觉信心倍增,当周就把 ACP 的流程走起来了。

随后就是又两个月的杳无音讯……

今年 1 月,@dtolnay 的指令流水线恰巧把这个 PR 调度上来,给我留了一个 Request Changes 让我修一下编译。发现我凭直觉写出来的合理代码遇到了另一个 Rust 编译器的 BUG 导致编译不过:

解决以后,社群志愿者 @tgross35 指导我给新的功能添加 unstable feature 的属性注解,也就是:

1
#[unstable(feature = "once_cell_get_mut", issue = "121641")]

另一位社群志愿者 @programmerjake 帮我指出几个文档注释的问题,为标准库添加新接口不得不写好接口文档,摆烂不了。

在此过程中,我给 OnceLock 也同样加了 get_mut_or_initget_mut_or_try_init 接口,因为它和 OnceCell 本来就是同期进来的,接口设计也一模一样。我想那就一起加上这个接口,免得 OnceLock 后面有同样的需要还要另走一次 ACP 流程。

这悄然间又是两个月过去了……

终于,在 @programmerjake Review 完之后一周,@dtolnay 出现并 Appove 后合并了代码。

第一次 Rust 主仓库参与贡献至此告一段落,唯一剩下的就是等 libs-team 主观认为合适之后启动功能 stabilize 的流程。

上个月,有人发现之前写的文档注释还是有错误,于是提交 PR 修复。这就是某种开源协同让代码质量向完美收敛的过程。

为什么会想到给 Path 加接口?

这个动机要追溯到我用 Rust 重写 License Header 检测工具 HawkEye 的时候了。

Rust 重写 HawkEye 的动机,则是为了支持调用 Git 库跟 gitignore 的机制做集成。虽然原先 Java 的实现可以有 JGit 来做,但是 JGit 的接口很脏,而且加上 JGit 以后就不能 Native Image 了导致分发产物体积显著变大。虽然都不是什么大事,但是工具类软件本来就是强调细节处的开发者体验,正好我逐渐掌握了 Rust 编码的技巧,就拿上来练练手。

今年 3 月重写 HawkEye 的时候,我发现了 Rust 标准库里 Path 结构缺一个接口:

1
2
3
4
let mut extension = doc.filepath.extension().unwrap_or_default().to_os_string();
extension.push(".formatted");
let copied = doc.filepath.with_extension(extension);
doc.save(Some(&copied))

我在写上面这段代码的时候,目的是给文件名加一个 .formatted 后缀。但是,Path 的 with_extension 接口是直接替换掉扩展名,也就是说,原本我想要的是 file.rs 变成 file.rs.formatted 的效果,如果用 with_extension 接口,就会变成 file.formatted 这样不符合预期的结果。

最终,只能用上面这样的写法手动绕过一下。显然代码变得啰嗦,而且这段代码是依赖 extension 的底层实现细节,某种程度上说是 brittle 的。

遇到这个问题的时候,我就想给标准库直接提一个新的 PR 了。不过当时 OnceCell 和 OnceLock 的 PR 还没合并,我拿不准 Rust 社群的调性,也不想开两个 PR 都长期 pending 下去。

好在上一个 PR 在几周后顺利合并了,我于是同时创建了 ACP 和 PR 以供社群其他成员评审。因为改动面很小,比起口述如何实现,不如直接在 ACP 里链接到 PR 讲起来清楚。

这次,提案很快得到 Rust 团队成员,也是我的前同事 @kennytm 的回应。不到两周,我就按照上次的动作把 PR 推到了一个可以合并的状态。

然后又是两个月的杳无音讯……

最后,我根据其他社群成员的指导,跑到 Rust 社群的 Zulip 平台上,在 libs-team 的频道里几次三番的问:“这个 ACP 啥时候上日程啊?”

终于,在今年 7 月初,libs-team 在会议上 appove 了 ACP 的提议,并在一周内再次由 @dtolnay 完成合并。

开发者的需求是开源贡献的源动力

可以看到,上面两个贡献的源动力,其实都是我在开发自己的软件的时候,遇到的 Rust 标准库缺失的接口,为了填补易用接口的缺失,我完成了代码开发,并了解社群流程以最终合并和发布。在最新的 Rust Nightly 版本上,你应该已经能够使用上这两个我开发的接口了。

在开源共同体当中,一个开发者应该能够发现所有的代码都是可以更改的。这是软件自由和开源定义都保证的事情,即开发者应该能够自由的更改代码,并且自由地使用自己修改后的版本。

那么,开发者在什么时候会需要修改代码呢?其实就是上面这样,自己的需求被 block 住的时候。小到 Rust 标准库里接口的缺失,大到我之前在 Apache Flink 社群里参与的三家公司合作实现 Application Mode 部署,甚至完全重新启动一个开源项目,说到底核心的源动力还是开发者真的对这样的软件有需要。

因此,开发者的需求是开源贡献的源动力。一旦一个开源软件不再产生新需求,那么它就会自然进入仅维护状态;而一旦一个开源软件不再能够满足开发者实际的需求,甚至开发者连直接修改代码的意愿也没有,那么它的生命也就到此为止了。

Logforth: 从需求中来的 Rust 日志功能实现

由此,我想介绍一个最近在开发 Rust 应用的时候,由自己需求出发所开发的基础软件库:

Logforth: A versatile and extensible logging implementation

Rust 生态的日志组件,由定义 Logging 接口的 log 库和实现 Logging 接口的各个实现库组成。其中,log 库可以类比 Java 日志生态里的 SLF4J 库,而日志实现则是 Logback 或 Apache Log4j 这样的库。实际上,Logforth 的名字就来自于对 Logback 的致敬。

编写 Logforth 的动机,是我在选择 Rust log 实现的时候,现有所有实现都不满足我的灵活定制需求。生态当中实际定位在完整 log 实现的库,只有 fern 和 log4rs 这两个。其中,fern 已经一年多没有新的发布了,一些显而易见的问题挂在那里,内部设计也有些叠床架屋。而 log4rs 则是对 Log4j 的直接翻译,也有许多非常诡异的接口设计(底层问题是 Java 的生态和设计模式到 Rust 不能直接照搬)。

于是,我花了大概两个小时的时间,梳理出 Rust 和 Java 日志生态里日志实现库的主要抽象:

  • Appender 定义日志写出到目标端的逻辑;
  • Filter 定义日志是否要打印的逻辑;
  • Layout 定义日志文本化的格式。

然后花了一天的时间,把 log4rs 的主要 Appender 即标准输出和(滚动)文件输出给实现了,同时完成了基本的基于日志级别的 Filter 和纯文本以及 JSON 格式的 Layout 实现,就此发布的 Logforth 库。

经过两周的完善,目前 Logforth 库已经具备了全部日志实现所需的基本能力,且可以自由扩展。接口都非常干净,文档也都补齐了。除我以外,一开始一起讨论需求的 @andylokandy 也极大地帮助了 API 的设计跟多种常用 Appender 的实现和优化。应该说,目前的 Logforth 已经是超越 fern 和 log4rs 的库了。

而回到本文的主题,之所以我能在一天时间内就写出第一个版本,我跟 @andylokandy 能目标明确、充满动力地实现 Logforth 的功能,就是因为看到了自己和整个 Rust 生态的需求,并且我们清楚应该怎么实现一个足够好的日志库。

Rust 生态的诸多潜在机会

最后,为坚持到这里的读者分享几个我看到的 Rust 生态潜在的机会。

总的来说,目前整个 Rust 生态接近 Java 1.5 到 1.7 时期的生态,即语言已经流行开来,核心语言特性和标准库有一些能用的东西,整体的调性也已经确定。但是,距离 Java 1.8 这样一个全面 API 革新的版本还有明显的距离,核心语言特性的易用性有很大的提升空间,标准库的 API 能用但算不上好用,开源生态里开始出现一些看起来不错的基础库,但是还远远没有达到 battle-tested 的状态。

第一个巨大的缺失点就是 Async Rust 的实用工具。我找一个 CountdownLatch 的实现,找了半天才发现去年底发布的 latches 库符合我的期待。要是去年我有这个需求,就真没人能搞定了。后来我要找一个 Async 版 WaitGroup 的实现,找来找去没有一个合适的,只能自己 fork waitgroup-rs 改改来用。

Crossbeam 是个很不错的高质量库,可惜它提供的是同步版本的并发原语,不能在 Async Rust 里使用。上面 latches 和 waitgroup-rs 单看实现得还可以。但是这种单文件库,真的很难长期维护,而且像 latches 这样一个结构硬整出各种 feature flags 的做法,其实是反模式的,没必要。

所以一个 async-crossbeam 可能是目前我最想看到的社群库,或许它可以是 futures-util 的扩展和优化。这些东西不进标准库或者事实标准库,各家整一个,真的有 C++ 人手一个 HashMap 实现的味道了。

第二个缺失点,顺着说下来就是 Async Runtime 的实现。Tokio 虽然够用,但是它出现的时间真的太早了,很多接口设计没有跟 Async Rust 同步走,带来了很多问题。前段时间 Rust Async Working Group 试图跟 Tokio 协商怎么设计标准库的 Async Runtime API 最终无疾而终,也是 Tokio 设计顽疾和社群摆烂的一个佐证。

async-std 基本已经似了,glommio 的作者跑路了,其他 xxx-io 的实现也有种说不出的违和感。这个真没办法,只能希望天降猛男搞一个类似 Java ExecutorService 这样的体系了。而且最好还要对 Send + Sync + 'static trait bound 做一些参数化,不用全部都强行要求……

IO 和 Schedule 虽然有关系,但还是不完全一样的概念。总的来说 Rust 生态里暂时没有出现跟 Netty 一样 battle-tested 的网络库,也没有能赶上 ExecutorService 生态的 battle-tested 的异步调度库。不过好的调度原语库还是有一些的,比如 crossbeam-deque 和 soml-rs 里的相关库,等待一个能合并起来做高质量 Runtime 的大佬!

第三个缺失点还是跟 Tokio 有关。应该说 Tokio 确实做得早而且够用,但是很多设计到今天看就不是很合适了,然而社群里用得还是很重,就变得更不好了。比如上面的 log 库,Tokio 生态里搞了个叫 Tracing 的跟官方 log 库不兼容的接口和实现,也是一大堆槽点。

这里想说的是 bytes 库。很多 Rust 软件闭眼睛就用 bytes 处理字节数组,这其实有很大的性能风险。例如,基于 bytes 搞的 PROST 就有一些莫名其妙的的多余拷贝,可参考《Rust 解码 Protobuf 数据比 Go 慢五倍?》。值得一提的是,PROST 也是 Tokio 生态的东西。

Apache OpenDAL 内部实现了一个 Buffer 抽象,用来支持不连续的字节缓冲区。这个其实也是 Netty 的 ByteBuf 天生支持的能力。如果现在 Rust 有一个 Netty 质量的网络库,有一个 ExecutorService 的接口跟一些基本可用而不像 tokio 一样全家桶的实现,再把文件系统操作搞好点,我想整个 Rust 生态的生产力还能再上一个台阶。

Rust 的 Async FileSystem API 实现现在没有一个能真正 Async 的,这个其实 Java 也半斤八两。不过 Rust 的 io::copy 不能充分利用 sendfile syscall 这个,就被 Java 完爆了。这点是 Apache Kafka 实现网络零拷贝的重要工程支撑。

最后一个,给国人项目做个宣传。Rust 的 Web 库也是一言难尽,同样是 Tokio 生态的 Axum 设计让人瞠目结舌,整个 Rust 生态对 Axum 的依赖和分发导致了一系列痛苦的下游升级体验,可参考 GreptimeDB 升级 Axum 0.7 的经历,至今仍然未能完成。

国内开发者油条哥搞的 Poem 是更符合 Web 开发习惯的一个框架,用起来非常舒服,也没有奇怪的类型挑战要突破。Poem 的最新版本号是 3.0.4 而不是像 Axum 的 0.x 系列,这非常好。

不过,Poem 的接口文档、回归测试跟一些细节的易用性问题,还需要更多开发者使用慢慢磨出问题跟修复。希望 Poem 能成为一个类似 Spring 的坚固 Web 框架,这样我写 Rust 应用的时候,也能省点心……

举个例子,我的一个 Poem 应用里有 query handle panic 的情况,就踩到了 Poem 一个并发对齐的设计没有处理 panic 的缺陷。当然,我顺手就给修了,所以新版本里应该没这个问题。

至于文档不全的例子,主要是错误处理的部分,应该需要更多最佳实践。

无论如何,目前 Rust 生态整体的生产力和生产热情,还是比 Java 要高出太多。长期我是看好 Rust 的发展的,短期我只能安慰自己 Netty 是一个在 Java 1.6 才出现,1.8 才开始逐渐为人熟知使用,5.x 胎死腹中,发展时间超过 15 年的项目,生态要发展并不容易了。

包书

作者 xrspook
2024年8月6日 08:44

当年今日

为什么要包书呢?小学的时候,我完全不知道。当时的书都是我妈和我妈爸给我包的,发下来的所有教科书,他们都会用日历纸帮我包起来。有可能是白色的日历纸,也有可能是塑料的日历纸。以前的挂历通常都是下面是白色的,上面那一层是塑料的,塑料的那个可能是任何图案,白色的那个只有最下面的那一条才是日历本来的作用,其它地方我也不知道为什么要搞那么大。那个日历与其说是用来看日期,不如说是挂在墙上的一个大海报。

语数英三科的课本,爸妈通常用白色的日历纸包裹,因为白色的那些纸通常质地都比较厚,比较结实。像美术那样的课本我妈可能用塑料的日历纸包裹,至于为什么要这样呢,我也不知道。小学时候的美术课如果没记错的话一周才上一次,所以使用的频率很低。小学低年级的时候,我根本没有收拾的习惯,我从来不会看课表,根据那天的课程把需要上课的东西带过去,而是不管三七二十一,全部课本都塞到书包里。爸妈用厚实的日历纸给我包语文数学的课本是对的。因为我是个很粗鲁的人。书本塞到书包里很容易就皱了。哪怕是包了皮,依然会皱。如果不加任何处理的话,书本的那个样子真的会有点不堪入目。有些书本一个学期还没上完,封皮就得换,因为上一个皮已经烂掉了。

上初中以后,父母就再也没给我包书,到小学高年级的时候,他们也没那么干了。我自己也没有那么干,因为觉得没有必要,同学们都不这么干了。有些这么干的同学,他们是从文具店买了专门的包书纸,五颜六色,很好看,但我知道父母肯定不会让我那样,所以我宁愿不包。到了高中的时候,突然我又觉得我要包书了。因为那个时候的课本变成很大一本,A4那么大。那如果不包,书本的角很容易会卷起来。那个时候父母已经控制不了我用什么东西去包书。所以我买了透明磨砂的塑料膜,那个东西比较厚,而且比较韧。那个时候我已经学会爱惜,而且那个材质也不容易被搞烂,唯一的难点就是包书的时候很难完美折出我想要的形状,只能用透明胶固定。

大学的时候根本没包过书。大学的课本都是很厚一本,但实际上学的内容并没有书本那么吓人。通常情况下一个星期的课程只会出现一次,大课一个星期会有两次,比如高数和英语。大学的我和小学的我根本是两个模式,去上什么课去带什么书,多一张纸都不会拿。

工作以后,我依然会买很多书,需要学习什么我就买什么。那些书我就放在办公室,有空的时候直接拿来学习。但我不确定我得花多长时间才能把那本书看完。放着放着可能因为湿度的原因,书的角就卷起来了。所以我又开始包书。工作以后,我当然不会买花花绿绿的包书纸,我也不会再破费买透明的塑料膜,我会直接去办公室拿几张A3的打印纸。万一那本书太厚太大,A3的打印纸包不住,我就直接不包了,改为把书的边都用透明胶贴一圈加固。。

小学的时候,我不知道为什么要包书,但工作以后,我觉得因为我有需要,所以我得这么干。

CommunityOverCode Asia 2024 参会纪实

作者 tison
2024年7月30日 08:00

CommunityOverCode Asia 2024 于 7 月 26 日到 28 日在杭州举行。其前身是 Apache 软件基金会一年一度的 ApacheCon 活动,通常会在多地分别举办。今年已经举行的是本次亚洲大会,以及 6 月在斯洛伐克举行的欧洲大会。10 月,北美大会将在丹佛举行,我也会在北美的会议上分享两个主题:

  • Mobilize Your Community Army: A Commercial OpenSource’s Perspective
  • Equip the Community with Test Suite: Best Practice from Apache OpenDAL and more

欢迎届时关注。

本文分享我在刚刚过去的 CommunityOverCode Asia 2024 大会上的见闻和体会。

会场体验

本次活动现场,主要分成以下四个部分:

  1. 主会场
  2. 各个分论坛的会场
  3. Workshop
  4. 开源集市等自由活动区域

Workshop 我没进去,不知道具体什么情况。

各个分会场的空间今年是有点狭小了,即使全部坐满,估计也就四十个人的水平。同时,狭小的空间里开猛烈的空调,相对来说更容易犯困或身体不适。我在各个分会场里都没有待太久的时间。

Community 分会场由于有几位海外讲师,并且确实到场的外国友人比较多,是唯一有文字同传的分会场。但是文字同传需要视线在讲师、PPT 和翻译软件上来回切换,且翻译有几秒钟的明显延迟,现场的外国友人普遍反应体验一般。

主会场是整个会场当中体验最好的一部分,屏幕比去年的屏幕看起来要大上很多。我想如果我在上面讲 Keynote 演讲,应该也不得不好好准备了(笑)。

巨大的主会场屏幕

最后,开源集市布置在一个狭小的过道上,整体体验上比较局促。不过参与展览的项目和组织倒是不错,我除了在 GreptimeDB 摊位上不定时刷新,也在 Apache 基金会摊位上客串大半个小时的 NPC 跟不少参会者做了交流。

Greptime 的文创广受好评

商业、开源以及出海

这次大会上我除了出品 Community 分论坛以外,主要参与分享了两个主题,分别是:

  • 第一天主会场的圆桌讨论《国际化的机遇和挑战》
  • 第二天 Community 分会场的主题分享《动员你的社群大军:商业开源视角下的开发者关系》

可以看到,两者围绕了商业、开源和出海等主题展开。

其中第一天的圆桌,本来我以为要讲一些比较 tough 的话题,比如开源社群国际化当中的挑战,商业开源出海如何取得成功,结果讨论的都是比较柔和的话题,包括应该什么时候做国际化,国内和海外参与者的不同,社群如何建设之类有定论的主题。整体气氛轻松欢乐。

社群成功的关键是及时响应;参与开源社群可以是轻松的

第二天的主题分享,由于事前我没有做好排练,外加分会场冷气 debuff 和我的演讲时间被压缩到了 15 分钟,整体分享效果应该说非常糟糕。我实际想说清楚的是:

  • 开源社群不同分类的动机及可持续的根基;
  • 商业开源的模式和商业与开源的共生关系;
  • 面向商业开源模式的开发者关系如何实施。

其中,我目前主要的观点是,持续的开源创造,要么是个人自己所需,自产自销;要么有其他收入来源,支付开源开发的成本。后者对于社群团队来说,就是募资和加入企业就职;对于商业团队来说,需要商业盈利,反哺上游开源软件,核心基础能力走开源孪生构建生态的同时帮助大众。大公司支持的企业开源,是特定的标准化工作能规避的巨大成本风险。

商业开源的理论蓝图

这个主题我会在 10 月北美的大会上再做一次英文演讲,应该到时候做好排练调整一下内容顺序,效果会更好一些。敬请期待到时的分享和专项说明文章。

此外,作为 Community 分论坛的出品人,本应由我担任的分论坛主持人一职,实际最后是 Ted Liu 和 Yu Liu 客串完成的。感谢两位的支持 :D

现场与场外的交流

虽然本次会场没有 Unconference 一类专门交流的节目,但是参会者在开源集市、会场休息处和其他场外地点做的交流可一点都不少。应该说,这样一场行业瞩目的开源峰会,来到现场的人在主题分享之外的交流,也是会议价值不可缺少的组成部分。甚至以其创造的价值总量而言,它是超过主题分享的。

夜话 ASF Culture

得益于来自中国的 ASF 董事姜宁老师亲自前往北美和欧洲的邀请,本次亚洲大会有很多外国友人参会和做分享。

由于我跟外国讲师恰巧都住在会场附近的酒店,在第二天晚上 Track Chair 聚会结束以后,我跟几位外国讲师回到酒店大堂边吃夜宵边聊起了在 ASF 的经历和各地文化的差异。

几位讲师都是游历各地的老江湖了,他们分享起各地的风俗和自己的人生经历,十分有趣。尤其是他们面对跟自己儿子乃至孙子同辈的我解释笑话里面的梗的时候,连比带划的介绍然后又想要跳过黄暴的部分,非常迫真。

线下交流会让每个人都发现,其实线上看起来一板一眼,只知道规则只关心编码的人,也是一个活生生的有自己生活的人。大家对生活的热爱和基本的品质是共通的,由此在线上产生矛盾的时候,也更容易站在对方的角度考虑其动机,而不是直接假定对方是故意搞破坏的恶人。

除了交流各地的文化和趣闻,作为资深的开发者和常年参与 ASF 事务的基金会成员,我们也交流了不少软件研发过程当中的经验、近期软件发展的趋势,以及对 ASF 文化、议事规则跟近期冲突争议事件的看法。我想,这就是 ASF 纪录片里提到的,ASF 最大的价值是其成员之间的共识,而这种共识是由每次具体的讨论反复达成和演进的吧。

在跟国内某开源软件基金会的朋友交流的时候,谈及 ASF 的流程和议事规则,我们都很惊讶 ASF 大量的步骤依赖于一个看起来很不可靠的“达成共识”。例如项目如何进入孵化器?只要孵化器的项目管理委员会(PMC)成员达成共识即可。进入孵化器的导师如何寻得?答案是只要项目足够有趣,不少 PMC 成员会志愿担任导师。孵化项目版本发布如何保证合规?几乎每时每刻都有导师志愿帮助检查,而且这种检查可能是非常严格的。

这种依赖志愿者的做法,并且数百名孵化器志愿者有着相似的共识,上万名 Committer 主观接受的理念,才是 ASF 有别于其他组织的核心竞争力。

虽然出于这次夜话 private 的性质,我没有留下合影。不过会场内单独的合影还是有的:

Craig L Russell

前几周去湾区的时候跟 Craig 吃了一顿泰国菜,听他吹牛在 IBM 和 Oracle 的工作经历,吹得太厉害忘记合影留念,这次可算补上了。

Justin Mclean

Justin 跟我介绍了几个他的拿手好菜。希望下次发版或者过提案的时候,别把我当成菜炒了 >~<

后起之秀的开源项目

大会现场有位中国开源的老玩家问我,是不是感觉每年参与开源大会的都是同一批人。我说或许主导国内开源方向,跟参与社群运营的主力军,这些年的中流砥柱都没有发生太大的变化,但是我作为 ASF 孵化器导师,不停地能看到新项目进来,还有新的开发者投身开源,从这个角度来讲,其实中国开源的新面孔还是非常多的。

今年让我印象深刻的后起之秀有这么三位。

第一位是在主会场做主题演讲的 Apache Fury 原作者杨朝坤(Shawn)。虽然他在分会场讲序列化框架的技术细节讲得那叫一个深入,但是在主会场上还是很好的把握了大众的需求,分享了一个 Side Project 如何从蚂蚁集团内部孵化,经历一次申请开源失败以后,通过一段时间的內源运营以后成功开源并进入 ASF 孵化的故事。

Apache Fury 的开源之旅

项目成功的故事是群众喜闻乐见的。Shawn 富有感染力的分享打动了现场的听众,Apache Groovy 的 PMC Chair Paul King 投喂了一个明知故问的技术问题,让 Shawn 有机会进一步展开作为跨语言 IDL-Free 的序列化框架 Fury 的设计优势。

Paul King 抛出“诱饵”问题

我客串了一把技术翻译

第二位是在主会场做闪电演讲,在 Community 分会场也做了分享的 Apache StreamPark Committer 张超(@VampireAchao)。作为一名 00 后程序员,他非常外向且思维活跃,编程技巧过关,假以时日应该会成为强大的开源开发者。

闪电演讲:Chrome 的 Debug 技巧

第三位是满会场宣传 Apache Amoro 的陈政羽。开源运营是一个富有挑战的领域,尤其是并非自己开发且独占主导权的项目,如何协调不同参与方的需求,跟核心开发者商量项目的定位和演讲方向,是非常不容易的。

经过本次会场讨论,Apache Amoro 当前的实质定位是增强 Apache Iceberg 的自动调优服务。一言以蔽之,Iceberg++ 是其核心价值点。不过这跟部分核心开发者希望兼容 Hudi 的负载,想开始超融合所有数据集成生态的目标有出入。我们可以拭目以待这个项目后续的发展,以及陈政羽在其中协调结果的成色🤣。

SelectDB 乱入 O_O

未来的开源峰会

CommunityOverCode Asia 2024 圆满结束。今年,国内还尚未开幕的开源峰会当首推开源社将于 11 月举办的中国开源年会(COSCon)。

定档 11.2-3,COSCon’24 第九届中国开源年会暨开源社十周年嘉年华正式启动!

巧合的是,今年是 Apache 软件基金会 25 周年,也是开源社成立的 10 周年。或许从未来回头看,今年会是中国开源继往开来的关键年😇。

此外,今年的 CommunityOverCode 大会还有 10 月的北美大会尚未举办。我将于 10 月到达丹佛会场做两个主题分享:

  • Mobilize Your Community Army: A Commercial OpenSource’s Perspective
  • Equip the Community with Test Suite: Best Practice from Apache OpenDAL and more

欢迎届时关注。

最后,去年和今年的 CommunityOverCode Asia 承办单位几乎都是贴钱办会,以至于活动组织者专门写了一篇文章“化缘”:

正在消亡的社区会议:呼吁更多伙伴持续支持阿帕奇亚洲大会的举办

我想,作为面向开发者的大会,最希望看到 CommunityOverCode Asia 顺利举办的,是每一位热爱开源的开发者。我向组织者建议,明年筹款的时候,其一可以实时公布筹款进度,让潜在的赞助者知道要想会议成功举办,还需要自己的多少支持;其二可以开通个人赞助的渠道,我想参与开源的开发者们众志成城,并不难凑齐这样一场年度盛会所需要的小几十万元人民币。

我在这里承诺,如果明年开通了个人赞助的渠道,我将以本人的名义或届时所在公司的名义,捐赠不少于十万元人民币以作支持。期待明年 CommunityOverCode Asia 越办越好!

Apache DataFusion 湾区线下聚会纪实

作者 tison
2024年7月15日 08:00

6 月 24 日,我在北美湾区参与了一场线下的 Apache DataFusion 聚会活动。

其实我是 6 月 21 日才到的旧金山,6 月 18 日才发现湾区有这样一场线下活动。不过或许得益于我在今年在 DataFusion 做过几次贡献,GreptimeDB 是 DataFusion 在行业顶级的应用标杆,会议组织方很干脆的就增加了一个 Speaker 席位,让我能够做在聚会上做题为《Boosting a Time-Series Database With Apache DataFusion》的演讲。

会议风格

本次 Meetup 一共报名 80 人,实际到场超过 50 人,绝对算是小型 Meetup 里的大型聚会了。现场是一位联合主办人的办公室,堪堪容纳所有人或站或坐待在室内。

我印象最深的是海外 Meetup 更加注重 Get Together 的风格,与国内 Meetup 基本是讲师从头讲到尾的风格的差异。

一般来说,国内的 Meetup 一个主题可以讲 30-40 分钟,4-6 名讲师讲完一个下午也就结束了。往往参与者也不怎么听完主题,而是逮到相关的到场专家,或者听到感性的主题以后,就拉着专家或讲师直接另开小会去了。

我刚报上名参加湾区 DataFusion Meetup 的时候,得到的消息是演讲时长 15-20 分钟,临了又改成 12-15 分钟。基本上一共六名讲师,从六点开讲,到七点半就完全讲完了。剩下的时间留给现场的观众自由交流,当然也有人拉着看对眼的与会者出去开小会,但是总体所有人都听完了所有主题,并且也还毫不疲倦。

这是国内不少活动最近有在参考的一个趋势。不管是年初 OSPO Summit 的 unconforence 环节,还是接下来几场 Apache 软件基金会的国内会议筹备的形式,都更加注重 Get Together 与会者自由交流,而不再是发布会形式的讲师从头讲到尾。

此外,海外的组织者对这样的小型聚会明显更有热情,他们有 lu.ma 和 meetup.com 等等丰富的宣传渠道,也乐于在湾区举办各种会议交流前沿进展。这点是国内近几年来声音比较弱的方面。

活动预告

在进入演讲内容回顾之前,先预告将在未来两周举办的两场 Apache 生态线下活动。

第一场是在 7 月 21 日下午杭州蚂蚁 A 空间举办的 Apache DataFusion Meetup 活动。GreptimeDB 核心工程师,同时也是 DataFusion 社群 PMC 成员夏锐航将会做深入的技术分享;蚂蚁集团工程师和 eBay 工程师也都将分享他们基于 DataFusion 构建出来的多样系统,参与 DataFusion 社群的故事,以及对 DataFusion 未来的看法。

欢迎点击链接( https://www.huodongxing.com/event/5761971909400?td=1965290734055 )报名,或扫描以下二维码报名。

第二场从 7 月 26 日开始持续 7 月 28 日。Apache 软件基金会年度活动 Community Over Code Asia 2024 今年也将在杭州举办。我将作为 Community 分会场的出品人参与活动并做演讲。GreptimeDB 的核心工程师,同时也是 OpenDAL 社群 Committer 的徐文康也将在 IoT 分会场上做技术分享。GreptimeDB 在现场另有展位介绍,我会全程在场(たぶん)。

欢迎通过这个链接( https://asia.communityovercode.org/zh/ )报名。

演讲内容

聚会上一共有八名讲师做了六个主题演讲,分别是:

  • LanceDB 的 CEO Chang She 分享了他们利用 DataFusion 实现向量计算的实践;
  • Cube.js 的 CTO Pavel Tiuvov 分享了基于 DataFusion 实现的查询缓存层;
  • DataFusion 的现任 PMC Chair Andrew Lamb 介绍了社群发展的近况和未来展望;
  • Denormalized 的创始人 Matt Green 分享了使用 DataFusion 实现流计算引擎的实践;
  • DataFusion 的原作者 Andy Grove 和他的同事分享了在 Apple 实现了 DataFusion Comet 做 Spark 查询加速实践;
  • 我介绍了 GreptimeDB 使用 DataFusion 和整个 FADOP 技术栈快速实现了一个高完成度的时序数据库的实践。

出于演讲时间限制,我的核心内容浓缩在了 GreptimeDB 如何使用和定制化 DataFusion 的实现上:

  • 每位分享嘉宾介绍的实践,都包含了在 DataFusion 这个执行引擎库之上实现的一个分布式计算框架。虽然 DataFusion 自己有一个子项目 Ballista 某种程度完成了这项任务,但是无论是成熟度还是它为大数据生态做的许多特化设计,都不适合上面这些使用场景的具体需求。

GreptimeDB 的分布式计算框架

  • GreptimeDB 从入口处直接重新实现的整套 PromQL 查询支持。DataFusion 主要支持的是 SQL 查询的解析、优化和执行,但是 GreptimeDB 为兼容 Prometheus 的生态,借助 DataFusion 封装的框架,将 PromQL 当做一种新的方言,通过实现 DataFusion 高度插件化的接口集成到了 DataFusion 的执行引擎当中。

值得一提的是,GreptimeDB 将 promql-parser 完全开源之后,已经成为所有想要实现 Prometheus 接口的 Rust 项目的统一选择。

GreptimeDB 实现了超过 80% 的 PromQL 接口

  • 另一项 GreptimeDB 突出的技术实现,是核心工程师钟镇炽主导开发的一个高度可扩展的索引框架。GreptimeDB 在此之上实现了 MinMax 索引和倒排索引的能力,并将在 0.9 版本里推出针对文本列的全文索引。我们计划将这一框架回馈给 DataFusion 上游,共同演进丰富查询引擎的共享代码。

GreptimeDB 强大的索引框架

  • 演讲之初,我介绍了 GreptimeDB 在时序数据领域上的关键理念创新:时序数据不仅仅是指标(Metrics),同样带有时间戳和上下文信息的数据,例如事件(Events)、日志(Logs)和追踪(Traces),都可以统一在一个时序数据库下进行处理。不仅能够同时优化负载和性能,降低成本,还能通过联合分析获得更加丰富的数据洞察。

统一 MELT 的时序数据处理

  • 最后,我实际超时了大概两分钟介绍了 GreptimeDB 得以快速实现一个高完成度时序数据库所依赖的技术栈:

FADOP Data Infra 技术栈

其中 FAD 都是原先 Apache Arrow 项目群的项目,分别是:

  • Apache Arrow
  • Apache Arrow Flight
  • Apache (Arrow) DataFusion

P 对应的是 Apache Parquet 项目,实际上大量的 Parquet 实现包括 Rust 实现,都包含在 Arrow 项目仓库里。

O 对应的是 Apache OpenDAL 项目。这是由来自 Databend 的工程师漩涡实现的统一数据访问层。接上它,你的项目就可以无痛对接上百个存储后端,包括几乎所有主流云厂商的对象存储服务,都可以用统一的 API 进行读写:用过的都说好。

社群发展

其他讲师大体也介绍了如何应用 DataFusion 的故事,而 DataFusion PMC Chair Andrew Lamb 则站在社群角度分享了 DataFusion 过去一年的进展,包括:

  • 超过 1000 个项目使用 DataFusion 构建自己的软件;
  • 正式从 Apache Arrow 的一个子项目,成为 Apache 软件基金会的顶级项目;
  • 遍布全球的用户会议,包括上面提到的杭州 Meetup 活动
  • 在 SIGMOD 2024 上发布了 DataFusion 的主题论文
  • 全球开发者合作实现的若干项功能,例如查询优化加速、索引加速和内存占用改进等等,其中不少功能是由中国开发者主导或参与实现的。

Andrew Lamb 确实是 10x 工程师

我在今年开始给 DataFusion 做一些实际的贡献,在此过程中深刻感受到了 Andrew Lamb 的热情和生产力。虽然他经常过分乐观的合并别人贡献的代码,导致一些回退(regression)跟接口需要重新适配,但是他 10x 甚至 100x 的生产力能够快速再次解决这些问题。我想这才是在开源社群协同当中真正 distinguished 的能力。正如 Linus 一样,他未必要独立写出 90% 的代码来推动项目前进,而是能每天合并来自全球各地的数十个 pull request 并保证它们相互之间没有实际冲突,也不会导致回退。

对于 DataFusion 这个项目,我的看法与其官方描述一致:

DataFusion is great for building projects such as domain specific query engines, new database platforms and data pipelines, query languages and more. It lets you start quickly from a fully working engine, and then customize those features specific to your use.

它有抽象层级非常高的 SQL 和 DataFrame 接口,能让你直接获得查询计算能力;对于数据库或其他查询系统而言,它也提供了高度可定制化的框架抽象。从纯粹技术理论上说,针对一个特定的数据系统,定制一个查询引擎总是能有最高的优化上限。但是很多时候,这未必是你的系统最核心的竞争力。

因此,就像 GreptimeDB 采用 DataFusion 的历史一样,我们发现这个软件库是一个很好的起点,扩展定制的旅程也很流畅。绝大部分情况下,我们对查询优化的投入程度和生产力是不如 DataFusion 上游的,我们会将这些时间和精力更多放在 GreptimeDB 作为一个统一时序数据库的业务逻辑实现,用户体验优化,以及从云到端的协同方案落地上。或许在未来的某一天,使用 DataFusion 的项目团队拥有足够多的开发者,能够针对自己的系统设计实现一个更加优秀的查询引擎;但是更有可能的是,终其软件一生,DataFusion 都是那个更好的框架和库实现。

❌
❌