首页 > 计算机 >

豆瓣的session cache

本文按署名·非商业用途·保持一致授权
作者:  ,发表于2007年11月30日23时20分 

这篇文章可能还会被更新,我是用mediawiki来管理的。为了不让11月份的blog留空,一边打星际一边赶着发出来了。

”’下面的session和cache可以认为是同一个东西”’

豆瓣改版之后,出现了下面的状况:
我的session id(在客户端的cookie变量名为dbcl2)是在改版之前获得的,以下内容在我用这个session id访问豆瓣的时候全部没有显示。
*我的好友
*我的小组
*我的资料:头像,自我介绍,常居地,blog地址,username
*我的豆邮
*我看过,读过,听过的东西,以及对应的标签
* 我对某个subject的评价(不过这个应该不是放在cache里的。没必要。)

我使用另外一个浏览器登录,也就是在我获取了一个新的session id之后,这些内容都可以全部正确显示了。也就是说,这些数据全部是存储在和session相关的缓存里。

而我使用另外一个浏览器登录之后,旧的session id还是可以使用。也就是,这个session id是不可以通过用户的id来关联到。豆瓣可能觉得做这个关联变量会增加复杂度,而且对服务器稍微增加了一点负载。

在这个旧的session id下,我加入了一个新组。于是在我的小组里,有了这个组的相关信息,但是其他组还是没有出现。也就是说,加入一个新组,会把这个组的基本信息(或许只是个id)加载进cache里,但是不会对这个session的全部小组信息进行更新。类似的,其他数据也应该是采用这样的处理方式。我后来又试了添加我看过的电影,确实如此。

那么究竟一个项目,会有什么信息被保存到cache里呢?首先,可以确定的是一个项目的id肯定是会被cache的。例如小组的id,subject的id。那么其他信息是否会被cache呢?我觉得大多数情况下其他信息不会被cache。那小组来说吧,如果把小组的名字,最新帖子都cache到每个人的session数据里的话,这个复杂度实在是太高了,要做到很及时地更新很困难。而且会给cache服务器带来不可估量的负载,这就失去cache的意义了。另外从上面一段提到的数据显示情况来看,豆瓣也并没有把其他信息cache到每个人的session数据,否则我的小组信息早就恢复。

这个cache机制是基于什么系统呢?登录的时候,豆瓣会问你是否记住我。里面注明“一个月之内不用再登录”。为什么是一个月的?如果豆瓣用的是memcached的话,这就很好解释了。因为memcached的一个记录的最长存储时间是30天。再加上最近几年几乎所有的web新贵,都是用memcached作为内存级别的缓存工具。所以豆瓣用memcached的可能性是非常大的。

那么如果我不选择“一个月之内不用再登录”的话,这个session会在服务器保留多长时间呢?我做了个测试,把一个这个条件下的session id保存起来。过了3个小时,这个session还是存在。这样看来,即使不选择一个月自动登录,这个session还是会保留一段比较长的时间。当然这个到底有多长,还得继续等待才能知道。

现在可以大致得出一些信息

豆瓣session cache的结构:
{
个人资料 {头像,介绍,常居地,blog,username};
友邻 {友邻ID1,友邻ID2,…};
小组 {小组ID1,…};
收到的豆邮 {id1,id2,id3,…};;
发出的豆邮 {id1,id2,id3,…}
看过的 {id1,id2,id3,…};
正在看的 {id1,id2,id3};
看过的标签 {标签1,标签2};
等等等…
}

对其中的一个子项目进行写操作,并不会重新加载这个项目的所有信息到session cache。例如我加了一个新组,不会重新把所有的小组信息加载进来;我发送了一个豆邮,也不会把我发送的所有豆邮加载进来。看来,豆瓣的缓存确实是够彻底的。即使你进个人设置里,如果你不做修改的POST提交,数据还是取自缓存,不给数据库任何机会。(不过豆瓣目前似乎只在数据层做缓存,没有在web层做例如反向代理之类的缓存。也不知道豆瓣是否有数据库层的冗余和分布机制。)

豆瓣的session id在客户端用一个名为dbcl2的cookie保存,豆瓣的缓存服务器软件使用的可能是memcached。

这样的缓存机制,确实省去了很多数据库方面的查询或者说把很多复杂的联合查询简化为简单的查询了。

我们再来看,为什么豆瓣没有发现这个session数据是错误的呢?我先列出整个流程
#改版之后,我第一次访问豆瓣。我的浏览器发送豆瓣的cookie到豆瓣的服务器,这些cookie其中有一个是session id。这个id是改版前获取的,也就是说session数据是改版前的。
#豆瓣的cache程序会判断这是否是一个合法的session id。这时候发生了什么事情呢?我架设豆瓣这次改版也对程序进行了改进。
#*情况一,豆瓣在改版前清空了所有的session,而他们的新程序有一个bug,判断这个session是否存在的时候出错。而我的这次访问,又正好在豆瓣的cache服务器建立起了这个空的session变量。
#*情况二,豆瓣的session数据结构发生了变化,而程序判断session合法性只是判断了这个session是否存在或者只是判断了某个 session的变量,而这个变量的值恰好在某些情况下在新程序里也是合法的。而由于数据结构发生了变化,这时候新程序是无法获取旧数据的。

不过情况二不太可能,如果是这个情况,那么遇到内容无法显示的用户应该是非常得多。但是按照我得到的信息,遇到这个问题的用户虽然不是只有我一个,但是也不是非常的多。

不过可以确认的是,这确实是一个bug,不过要真正查出错误所在,就得结合豆瓣的相关程序来分析和测试了。



6个评论

  1. xdanger:

    分析得很好,很强大。
    豆瓣还有低级的XXXX漏洞,好像还没改掉,很口水啥时候搞一下。
    还有豆瓣用的 Lighttpd 不是 1.4.18 的,据可靠消息,可以被瞬间挂马,获取 root。

  2. 免费电话:

    高人啊,这些漏洞的利用方法应该公布个思路

  3. xinple:

    很好玩的样子,很好玩的陈泽,:)

  4. 化妆品:

    写的很好哦!
    可以到乐偶网 http://www.leall.com 发表一下,让更多人知道。

  5. mini storage:

    事在人為嘛. 不過, 大環境實在變得太快. 今天的標準可以是明日黃花!

  6. pecl::memcache的哈希策略:

    [...] 插一句:相对于VeryCD,豆瓣可能对这个存活率比较重视,因为他们的session是存储在memcache里的,客户端只有一个session id。如果session失效,那么就会导致用户的登录退出。而VeryCD,除了session id,还把一个用来认证的串存储在客户端的cookie里。如果session失效,会尝试使用这个认证串来重新登录,重建session。 [...]

发表评论

  本站文章若无注明,则以署名·非商业用途·保持一致授权
  桂ICP备05004302号 感谢医元网提供主机 感谢WordPress提供本程序 本模板下载