当年 1.6 亿美金估值的公司—— Digg 是如何被一句 Python 函数可变默参 毁掉的

2018-07-03 16:18:14 +08:00
 est

https://lethain.com/digg-v4/

太戏剧性了。画重点:

2011 年,Google 推出「 Panda 」 机制动摇了很多老的 SEO 手段,digg 流量被腰斩。推出 DiggV4 作战计划。经过紧张的开发发布,不过访客页面没问题,已登录用户打不开 MyNews 页面。开发不得不用临时手段把登录用户的默认页面改成 TopNews

MyNews 只能通过不断重启进程才能短暂修复。初期以为是 cassandra 的缓存击穿了 memcache,后来加紧用 redis 重写了,还是得几个小时重启一次

(折腾了一个月之后)

终于发现原因了:API 服务器是 tornado 写的名字叫 Bobtail。里面最常用的函数是:

def get_user_by_ids(ids=[])

然后这个 ids 就一直被 append 直到撑爆内存

所以这个 MyNews 功能也渐渐用的人少,因为没法定制化看新闻,后来,大家都不去 diggv4 而去 reddit 了。。

后来,digg 以 50w 美金被别人收了。。

作为这次 digg v4 事件的受害者,觉得太神奇了。。

20691 次点击
所在节点    Python
80 条回复
monsterxx03
2018-07-04 09:48:23 +08:00
@wwqgtxx 对, 忘记说了,3.4 开始不受这个影响了,生产环境还是 2.7
misaka19000
2018-07-04 10:02:33 +08:00
我一直不知道原来不能用可变参数作为默认变量,不过每次当我想这样尝试的时候 Pycharm 都会有警告,所以我从来没有真正的这样干过~~现在总算知道是什么原因了
jimi2018
2018-07-04 10:08:28 +08:00
哎,程序员很重要啊。
susucoolsama
2018-07-04 10:17:39 +08:00
这些坑真的是语言的设计缺陷吧,我觉得,开发者只有避免了。
hubqin
2018-07-04 10:21:01 +08:00
默认参数应该改成不变对象`None`:
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
ihipop
2018-07-04 10:35:36 +08:00
用好的 IDE 这种坑都会被 IDE 标出来的。非得用什么 VIM 不装任何语法分析插件什么的,就得保证自己有足够好的基本功底。
fwee
2018-07-04 11:09:59 +08:00
闭嘴!这是一个 feature !!
Linxing
2018-07-04 14:43:29 +08:00
@cf472436288 要求啥经验
noNOno
2018-07-04 14:59:36 +08:00
可真是值钱的 bug
risent
2018-07-04 15:37:23 +08:00
我去, 这锅当年是算在 cassandra 头上的,同一时期很多公司包括 Twitter 也在准备迁移到 cassandra,出了 digg 这档子事后都赶紧拉倒了。
cassandra 背锅这么多年啊!!
standin000
2018-07-04 16:20:50 +08:00
reddit 也是 python 写的,不过最开始是 lisp 的
yongzhong
2018-07-04 16:29:01 +08:00
@monsterxx03 看过这个工具,但一直不了解在生产环境怎么使用,hardcode 到代码中然后灰度到集群上进行观察?
kappa
2018-07-04 16:30:32 +08:00
@risent 貌似当时的新闻说是 CTO 因为选型 Cassandra 引咎辞职?
monsterxx03
2018-07-04 16:44:58 +08:00
@yongzhong 最好能先定位有问题的大概代码段, 写个脚本离线 benchmark 下, 完全没头绪就只能 hardcode 到代码里线上测了, 要小心点(比如 10% 的采样执行), 性能影响没测过.
est
2018-07-04 17:03:23 +08:00
@kappa reddit 也是 cassandra。。。
reus
2018-07-05 09:05:28 +08:00
坑是小坑,但是如果要你在一大堆代码里定位出这个,估计楼上一些冷嘲热讽的人,一个月都不行吧。
这是语言设计上的问题,这个行为是和直觉相悖的。因为每次函数调用,参数都是独立的,大部分人都会有这个直觉,但谁知道默认参数居然是每次调用都共用的呢?
js、ruby 的行为都不是这样,估计 python 这样的,仅此一家了。
ericgui
2018-07-05 09:35:12 +08:00
由于一颗钉子输了一场战争,最后覆灭一个王国,

这个事,似乎有点夸大。
shyangs
2018-07-05 11:18:38 +08:00
https://www.v2ex.com/t/163431
我在這裡吐槽過, 還被 Pythoneer 說這是特性, 不是坑.
Ehco1996
2018-07-08 10:52:29 +08:00
@monsterxx03 我的问题也排查出来了,就是 pyopenssl 的锅
XuAaron
2018-07-13 15:45:03 +08:00
@tabris17 这点还好,关键是列表可变。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/467817

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX