Submitted by gouki on 2012, June 8, 9:49 PM
本文来自infoQ,关注它的原因是因为又拍网这种图片超多而且文件较小的架构,我在不久的将来可能会遇到这个问题。所以先了解一下。
原文地址是:http://www.infoq.com/cn/articles/yupoo-partition-database
我这里只做摘要,如果要看,还是直接看原文吧:
分库设计
和很多使用MySQL的2.0站点一样,又拍网的MySQL集群经历了从最初的一个主库一个从库、到一个主库多个从库、 然后到多个主库多个从库的一个发展过程。
最初是由一台主库和一台从库组成,当时从库只用作备份和容灾,当主库出现故障时,从库就手动变成主库,一般情况下,从库不作读写操作(同步除外)。随着压力的增加,我们加上了memcached,当时只用其缓存单行数据。 但是,单行数据的缓存并不能很好地解决压力问题,因为单行数据的查询通常很快。所以我们把一些实时性要求不高的Query放到从库去执行。后面又通过添加多个从库来分流查询压力,不过随着数据量的增加,主库的写压力也越来越大。
在参考了一些相关产品和其它网站的做法后,我们决定进行数据库拆分。也就是将数据存放到不同的数据库服务器中,一般可以按两个纬度来拆分数据:
垂直拆分:是指按功能模块拆分,比如可以将群组相关表和照片相关表存放在不同的数据库中,这种方式多个数据库之间的表结构不同。
水平拆分:而水平拆分是将同一个表的数据进行分块保存到不同的数据库中,这些数据库中的表结构完全相同。
拆分方式
一般都会先进行垂直拆分,因为这种方式拆分方式实现起来比较简单,根据表名访问不同的数据库就可以了。但是垂直拆分方式并不能彻底解决所有压力问题,另外,也要看应用类型是否合适这种拆分方式。如果合适的话,也能很好的起到分散数据库压力的作用。比如对于豆瓣我觉得比较适合采用垂直拆分, 因为豆瓣的 各核心业务/模块(书籍、电影、音乐)相对独立,数据的增加速度也比较平稳。不同的是,又拍网的核心业务对象是用户上传的照片,而照片数据的增加速度随着 用户量的增加越来越快。压力基本上都在照片表上,显然垂直拆分并不能从根本上解决我们的问题,所以,我们采用水平拆分的方式。
拆分规则
水平拆分实现起来相对复杂,我们要先确定一个拆分规则,也就是按什么条件将数据进行切分。 一般2.0网站都以用户为中心,数据基本都跟随用户,比如用户的照片、朋友和评论等等。因此一个比较自然的选择是根据用户来切分。每个用户都对应一个数据 库,访问某个用户的数据时, 我们要先确定他/她所对应的数据库,然后连接到该数据库进行实际的数据读写。
那么,怎么样对应用户和数据库呢?我们有这些选择:
按算法对应
最简单的算法是按用户ID的奇偶性来对应,将奇数ID的用户对应到数据库A,而偶数ID的用户则对应到数据库B。这个方法的最大问题是,只能分成两 个库。另一个算法是按用户ID所在区间对应,比如ID在0-10000之间的用户对应到数据库A, ID在10000-20000这个范围的对应到数据库B,以此类推。按算法分实现起来比较方便,也比较高效,但是不能满足后续的伸缩性要求,如果需要增加 数据库节点,必需调整算法或移动很大的数据集, 比较难做到在不停止服务的前提下进行扩充数据库节点。
按索引/映射表对应
这种方法是指建立一个索引表,保存每个用户的ID和数据库ID的对应关系,每次读写用户数据时先从这个表获取对应数据库。新用户注册后,在所有可用 的数据库中随机挑选一个为其建立索引。这种方法比较灵活,有很好的伸缩性。一个缺点是增加了一次数据库访问,所以性能上没有按算法对应好。
比较之后,我们采用的是索引表的方式,我们愿意为其灵活性损失一些性能,更何况我们还有memcached, 因为索引数据基本不会改变的缘故,缓存命中率非常高。所以能很大程度上减少了性能损失。
索引表的方式能够比较方便地添加数据库节点,在增加节点时,只要将其添加到可用数据库列表里即可。 当然如果需要平衡各个节点的压力的话,还是需要进行数据的迁移,但是这个时候的迁移是少量的,可以逐步进行。要迁移用户A的数据,首先要将其状态置为迁移数据中,这个状态的用户不能进行写操作,并在页面上进行提示。 然后将用户A的数据全部复制到新增加的节点上后,更新映射表,然后将用户A的状态置为正常,最后将原来对应的数据库上的数据删除。这个过程通常会在临晨进行,所以,所以很少会有用户碰到迁移数据中的情况。
当然,有些数据是不属于某个用户的,比如系统消息、配置等等,我们把这些数据保存在一个全局库中。
--------
问题我就不列了,其实各种问题都会遇到的....
//...................这是缓存的问题,我也准备这么处理
revision信息也是存放在缓存里的,Key为Photos-revision。这样做看起来不错,但是好像列表缓存的利用率不会太高。因为我 们是以整个数据类型的revision为缓存Key的后缀,显然这个revision更新的非常频繁,任何一个用户修改或上传了照片都会导致它的更新,哪 怕那个用户根本不在我们要查询的Shard里。要隔离用户的动作对其他用户的影响,我们可以通过缩小revision的作用范围来达到这个目的。 所以revision的缓存Key变成Photos-{shard_key}-revision,这样的话当ID为1的用户修改了他的照片信息时, 只会更新Photos-1-revision这个Key所对应的revision。
因为全局库没有shard_key,所以修改了全局库中的表的一行数据,还是会导致整个表的缓存失效。 但是大部分情况下,数据都是有区域范围的,比如我们的帮助论坛的主题帖子, 帖子属于主题。修改了其中一个主题的一个帖子,没必要使所有主题的帖子缓存都失效。 所以我们在DBTable上增加了一个叫isolate_key的属性。
Tags: 又拍网, infoq
Misc | 评论:0
| 阅读:13441
Submitted by gouki on 2012, June 7, 8:48 AM
什么 是jquery BBQ?
这是一个jquery插件,BBQ的意思是back button & query。你知道的,以前的jqueryTAB在点击后都无法通过后退和前进恢复原来的点击事件等。而BBQ在每次点击的时候都相当于在历史里加入了一个记录。也就因此可以使得我们能够通过浏览器的前进、后退来重现刚才的点击。
官网在这里:https://github.com/cowboy/jquery-bbq
jQuery BBQ leverages the HTML5 hashchange event to allow simple, yet powerful bookmarkable #hash history. In addition, jQuery BBQ provides a full .deparam() method, along with both hash state management, and fragment / query string parse and merge utility methods.
This plugin and the jQuery urlInternal plugin supersede the URL Utils plugin.
- Release v1.2.1
- Tested with jQuery 1.3.2, 1.4.1, 1.4.2 in Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome 4-5, Opera 9.6-10.1, Mobile Safari 3.1.1.
- Download Source, Minified (4.0kb)
- Follow the project on GitHub project page or report a bug!
- View Full Documentation
- View Unit Tests
- Examples: basic hashchange, advanced hashchange, jQuery UI Tabs history & bookmarking, jQuery.deparam
- Translations: Belorussian
Note: If you’re using jQuery 1.3.2 or earlier and need BBQ to merge query string or fragment params containing []
, you’ll want to include the jQuery 1.4 .param
method in your code.
Also, my article Cooking BBQ: the original recipe gives a history of jQuery BBQ along with some plugin authoring guidelines, if you’re interested.
What jQuery BBQ allows you to do:
While this brief overview will give you the broad strokes, for specifics you should look at the the basic examples below, read the documentation, and check out the full examples listed above.
- Deserialize any params string, the document query string or fragment into an object, including the new jQuery.param format (new in jQuery 1.4, read more here). (example)
- Merge any URL plus query string or fragment params—in an object, params string or second URL (including the current document location)—into a new URL.
- Update the “URL attribute” (ie.
a[href]
, img[src]
, form[action]
, etc) in multiple elements, merging any URL plus query string or fragment params—in an object, params string or second URL (including the current document location)—into a new URL, which is then set into that attribute.
- Push (and retrieve) bookmarkable, history-enabling “state” objects or strings onto the document fragment, allowing cross-browser back- and next-button functionality for dynamic web applications (example 1, example 2, example 3)
- Bind event handlers to a normalized, cross-browser hashchange event (example 1, example 2, example 3)
These working examples, complete with fully commented code, illustrate a few ways in which this plugin can be used.
http://benalman.com/code/projects/jquery-bbq/examples/fragment-basic/
http://benalman.com/code/projects/jquery-bbq/examples/fragment-advanced/
http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/
http://benalman.com/code/projects/jquery-bbq/examples/deparam/
Tags: jquery, jquery-bbq
Javascript | 评论:1
| 阅读:24910
Submitted by gouki on 2012, June 6, 10:35 PM
这是一篇2年前的文章,之所以会再拿出来说,主要还是因为其中的一些话仍然在打动我。虽然时隔两年,但这些内容并没有过期。
原文在:Flipboard:iPad 上的革命性社交新闻应用初探
部分摘要:
- 什么是 Flipboard?它做了一件非常简单的事情:把你的 Twitter 和 Facebook 变成了一本杂志。你还可以建立一个自定义的杂志,要么选用 Flipboard 内建的版面,要么直接导入Twitter 的列表。这是一个非常强大而且使用感受十分美妙的 Twitter 阅读方式。同样的,你也可以把个人 Twitter 帐号、或者某个品牌的 Twitter 帐号转换成 Flipboard。你可以在 Twitter上 跟随 Techcrunch,然后使用这个应用把 Techcrunch 转换为漂亮的像杂志一样的界面,这样的界面比任何其他阅读器都要容易阅读。
- 对于视觉的研究证明,如果一个页面有一行大标题,是其它标题的两倍,这个页面更可能被人们所阅读。图片也同样,如果你在一个页面上放的图片是同样尺寸,另 一个页面上放的图片中有一个图片比其它图片大两倍,人们会更加注意有大尺寸图片的那个页面。我们的大脑就是这样工作的,一个大的标题和图片在我们观看页面 的时候提供了一个进入点。
- Flipboard 是怎样做到这一切的?毕竟,我的账户在 Facebook 上有 1800 个好友,而在 Twitter 上,我跟随了 19,000 人,但 Flipboard 仍然成功过滤了绝大多数的“杂讯”(其他客户端没有这个功能)。事实上,它有自己的一套逻辑来选择关联性最大的内容。比如说:有大量评论的,很多人喜欢 的,很多人 retweet 的。它还会根据状态信息的内容来过滤相关的图片并把它们显示出来。(膘叔:不要相信这些话,如果这是真的,那人人都能做了。)
- 站在内容创造者的立场,我很担心这会将过多品牌效应和广告利益从他们身边抽离。比如,我分享 Techcrunch 的文章的话,得到的好处还要多于在他们的内容被分享到 Flipboard 中得到的。这 可不好。而且内容创造者也需要一个更好的方式来告知 Flipboard 他们在用的正文篇幅。现在 Flipboard 只是通过内容创造者的 RSS 种子来分析他们的同步规则,究竟是全文输出、部分输出还是仅输出标题,但是 Flipboard 需要和内容方就其自身意愿进行沟通,因为我相信很多内容创造方不会乐于见到目前他们在 Flipboard 中所呈现的内容。站在用户的角度,我发现这种阅读体验很棒,所以媒体还是应该和 Flipboard 多沟通、合作,而不是如默多克(Rupert Murdoch )一样激动失控。
-
位于加利佛尼亚 Palo Alto 的 Flipboard 公司创始人是 Mike McCue,Tellme 和 Evan Doll 的前 CEO,曾在苹果公司做过iPhone 高级工程师。
Flipboard 刚收购了 Ellerdale,这个公司开发了一组基于 Twitter 的实时搜索工具。Ellerdale 的联合创始人 和 CTO Arthur van Hoff 做为 CTO 加入了 Flipboard 公司。
van Hoff 说有两年历史的 Ellerdale 一开始的目的是开发一个个性化的网络产品,但是投资者认为风险大,所以它先开发了技术,然后找到了用武之地。只有到了现在,那个最初的主意才有了价值。 “我们一直在开发一个伟大的分析引擎,但我们没有找到将内容分类导出的传导机制,我们的站点只是一个演示,不是一个产品,现在加入 Flipboard 之后,我们有了一个伟大的产品“。
McCue 说 Flipboard 一开始会是一个免费应用,在未来,公司会探索广告,订阅模式,以及和出版商分享收入。公司也计划尽快加入其它的内容渠道,比如 Tumblr, LinkedIn 和 Yelp。
Flipboard 现在有 1050 万(10.5 million dollars)的投资,来自 Kleiner Perkins 和 Index Ventures。其它投资的风投包括 Twitter 的创始人 Jack Dorsey,Google 投资人 Ron Conway,Facebook 联合创始人 Dustin Moskovitz,Peter Chernin创立的 Chernin Group, Alfred Lin, Peter Currie, Quincy Smith, actor/entrepreneur Ashton Kutcher, 主流投资商 Kleiner Perkins Caufield & Byers, and Index Ventures。
--------以上这段是来自2010年的文章,其实也说明了几件事:
- flipboard 不是一个晚上造出来的,他基于了Ellerdale和Readability,这两家公司在事先都存活了多年,摸索了多年
- flipboard也是摸着石头过河,10年的时候,他们最多只有9个格子。而如今是2页的九宫格+列表
- 商店的变迁也是颇为巨大,从聚合到分散再到聚合。这其中经历了多少。。。
--------
准备转行做产品了。所以开始对一些内容进行慢慢研究。
Misc | 评论:0
| 阅读:15956
Submitted by gouki on 2012, June 5, 10:25 PM
不是说真的没用。但是真有可能,以前我的显示器就是22寸的,那时候外面都还是19寸,我用的很爽。屏幕大,用的爽。。。
当然我现在也希望有大屏幕的,但好象不太现实了。我当然希望有一台iMAC,一台17的mbp,两台一起用。但好象有点不太现实。光这两样东西,就要将近4W了。但真正算起来,这些其实也并没有多少钱。相对于一名开发人员的薪水来说。无非就是挤挤乳沟就有了。但为什么很多公司就是不愿意投入这些呢?不明白。真的不明白,好象越是把硬件搞的越便宜就越开心。
----以下是内容,来自:http://news.cnblogs.com/n/144016/
英文原文:Why Quit? Because They Have Bigger Monitors
好的技术人员向往具有很强的企业技术文化氛围的工作场所。但如何你能从外部看清一个企业的技术文化状态?这里要讲的是我使用的两个简单而好用的参考指标。
首先我要讲讲“企业技术文化”这个词指的是什么。它是指技术人员在一个企业内受重视的程度和重要性。它能从一些事情上体现出来:
- 公司里的决策是如何制定出来的?在一个具有很好的技术文化的公司里,技术人员参与要做什么、何时做、由谁来做等决策制定。并不是说有最终拍板权,而是有真正的发言权。
- 对开发软件这个工种是否尊重?开发软件是一种创造性的工作,这种工作需要有合适的时间和合适的地点。有些项目很难预测出究竟要多久才能开发出来,而公司能认可这种情况。
- 基础设施。当需要把精力放到非软件特征功能方面的事情上时,明白事理的人(技术人员,经理)需要花多少的口舌才能让老板知道这些工作的重要性?这通常是指一些运行时系统里的工作(比如扩充消息队列容量)或后勤服务工作(例如编译系统或版本控制工作)。
不幸的是,想通过一次交谈咨询就把这种底细都摸清是不现实的,除非你在这个公司内部有受信任、知道内情的线人。
他们的显示器有多大?
发生在我的前一个公司里的故事。我当时是技术经理,试图想挽留一个人才。团队里有个程序员辞职要去一个很小的但很新潮的公司。下面是我跟他离职前的谈话:
我: 为什么要走?
他: 因为他们的显示器很大。
我: (怀疑) 开什么玩笑?我们也可以给你配个大显示器。
他: 并不只是我——每个人都需要大显示器。
我: 这有那么重要吗?
他: 这反映了公司如何看待我的时间的价值。公司需要决定的是,多花一些钱买个大显示器让更多的像素映入我的视网膜是否值得。
现在我明白了,他说的一点没错。重视员工的公司会认为设备上的额外开销相比起提高员工的工作效率(和提升他们的幸福感)来说,后者更重要。让最好的程序员使用最好的开发工具来工作。大个儿的显示器是一个非常醒目的判断指标。
员工是否可以选择他们自己的邮件地址?
非技术人员很多时候并不认为邮件地址有多么的重要。可它是你网上的身份证。严格的邮件地址命名规范(姓的全拼加名的缩写,或更糟糕的名的缩写加 姓的全拼)反映出公司重视所谓一致性超过对员工的心情的关心。更糟糕的是,这种规定非常直白的让员工们感觉到自己被当成了“齿轮”或“人力资源”,而不是 一个了不起的个人。
(旁白: 让我们远离“人力资源”这个词儿。太难听了。)
这一点对我个人而言格外重要,因为我有一个很独特的名。如果你不允许我的邮件地址为sef@company.com
,那你在我的印象里会大打折扣。不仅如此,冗长的邮件地址名让人产生错觉,就好象是个邮件列表地址,但里面只有一个成员,可以忽略不计。它很重要,它是你 shell 环境的提示符;它很重要,它是whoami
命令的返回值。
最后一句话:我并不是在谴责你们这些不辞辛劳的搞 IT 的男孩和女孩们。你们让很重要的东西保持正常运转,但还不得不被迫遵守这些强加的规则。相反,我针对的是这些糟糕的制度(通常是根植于糟糕的企业文化 中),是它们使你们处于糟糕的境地。如果你身处这样的一个公司里,那跪下来吧,祈求阳光的降临。
Tags: 跳槽, 显示器
Misc | 评论:0
| 阅读:12985
Submitted by gouki on 2012, June 5, 9:23 PM
Yiiredis是Yii的一个插件。用来方便我们对redis进行操作。封装了一些常用的list,hash之类的操作,对于Cache也做了一个封装,但在方便之余,问题也还是不少。比如说,我们要对数据sort,取出平均值,取出最大值之类的。默认的方法就不能用了。虽然yiiredis的类用了Array的interface,但利用php的操作,总归不如redis自身的操作。
一些参考资料上就写的比较详细:
典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:
-列出前100名高分选手
-列出某用户当前的全球排名
这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。
模式是这样的,每次获得新得分时,我们用这样的代码
- ZADD leaderboard <score> <username>
你可能用userID来取代username,这取决于你是怎么设计的。
得到前100名高分用户很简单:ZREVRANGE leaderboard 0 99。
用户的全球排名也相似,只需要:ZRANK leaderboard <username>。
看上去也比较方便,不过我没有仔细看究竟是因为phpredis的实现有问题还是yiiredis的问题。等晚上睡不着的时候看看伦家的源码先
Tags: yiiredis
PHP | 评论:0
| 阅读:16303