<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title> &#187; 网站架构</title>
	<atom:link href="http://www.liguosong.com/category/%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.liguosong.com</link>
	<description></description>
	<lastBuildDate>Tue, 08 May 2018 01:02:19 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.2</generator>
		<item>
		<title>优酷网架构学习笔记(转载)</title>
		<link>http://www.liguosong.com/2013/07/18/%e4%bc%98%e9%85%b7%e7%bd%91%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/</link>
		<comments>http://www.liguosong.com/2013/07/18/%e4%bc%98%e9%85%b7%e7%bd%91%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/#comments</comments>
		<pubDate>Thu, 18 Jul 2013 13:27:23 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[网站架构]]></category>

		<guid isPermaLink="false">http://www.liguosong.com/?p=158</guid>
		<description><![CDATA[一：数据库架构 &#160; 经历过才会有更深的体会吧，就像MySpace的架构经历一样，架构也是一步步慢慢成 [...]]]></description>
				<content:encoded><![CDATA[<p><strong>一：数据库架构</strong></p>
<p>&nbsp;</p>
<p>经历过才会有更深的体会吧，就像<a href="http://www.itivy.com/ivy/archive/2011/3/7/634351257301504864.html" target="_blank">MySpace的架构经历</a>一样，架构也是一步步慢慢成长和成熟的。<span id="more-158"></span></p>
<p><strong>1、简单的MySQL主从复制:</strong></p>
<p>MySQL的主从复制解决了数据库的读写分离，并很好的提升了读的性能，其原来图如下：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151549_5879.jpg"><img class="alignnone size-full wp-image-159" alt="20110910151549_5879" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151549_5879.jpg" width="621" height="495" /></a></p>
<p>&nbsp;</p>
<p>其主从复制的过程如下图所示：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151641_1001.jpg"><img class="alignnone size-full wp-image-160" alt="20110910151641_1001" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151641_1001.jpg" width="726" height="536" /></a></p>
<p>&nbsp;</p>
<p>但是，主从复制也带来其他一系列性能瓶颈问题：</p>
<ol>
<li>写入无法扩展</li>
<li>写入无法缓存</li>
<li>复制延时</li>
<li>锁表率上升</li>
<li>表变大，缓存率下降</li>
</ol>
<p>那问题产生总得解决的，这就产生下面的优化方案，一起来看看。</p>
<p><strong>2、MySQL垂直分区</strong></p>
<p>如果把业务切割得足够独立，那把不同业务的数据放到不同的数据库服务器将是一个不错的方案，而且万一其中一个业务崩溃了也不会影响其他业务的正常进行，并且也起到了负载分流的作用，大大提升了数据库的吞吐能力。经过垂直分区后的数据库架构图如下：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151747_8225.jpg"><img class="alignnone size-full wp-image-161" alt="20110910151747_8225" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151747_8225.jpg" width="788" height="543" /></a></p>
<p>&nbsp;</p>
<p>然而，尽管业务之间已经足够独立了，但是有些业务之间或多或少总会有点联系，如用户，基本上都会和每个业务相关联，况且这种分区方式，也不能解决单张表数据量暴涨的问题，因此为何不试试水平sharding呢？</p>
<p><strong>3、MySQL水平分片（Sharding）</strong></p>
<p>这是一个非常好的思路，将用户按一定规则（按id哈希）分组，并把该组用户的数据存储到一个数据库分片中，即一个sharding，这样随着用户数量的增加，只要简单地配置一台服务器即可，原理图如下：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151842_9228.jpg"><img class="alignnone size-full wp-image-162" alt="20110910151842_9228" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110910151842_9228.jpg" width="831" height="492" /></a></p>
<p>&nbsp;</p>
<p>如何来确定某个用户所在的shard呢，可以建一张用户和shard对应的数据表，每次请求先从这张表找用户的shard id，再从对应shard中查询相关数据，如下图所示：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110910152117_6934.jpg"><img class="alignnone size-full wp-image-163" alt="20110910152117_6934" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110910152117_6934.jpg" width="805" height="540" /></a></p>
<p>&nbsp;</p>
<p>但是，优酷是如何解决跨shard的查询呢，这个是个难点，据介绍优酷是尽量不跨shard查询，实在不行通过多维分片索引、分布式搜索引擎，下策是分布式数据库查询（这个非常麻烦而且耗性能）</p>
<p><strong>二、缓存策略</strong></p>
<p>貌似大的系统都对“缓存”情有独钟，从http缓存到memcached内存数据缓存，但优酷表示没有用内存缓存，理由如下：</p>
<ol>
<li>避免内存拷贝，避免内存锁</li>
<li>如接到老大哥通知要把某个视频撤下来，如果在缓存里是比较麻烦的</li>
</ol>
<p>而且Squid 的 write() 用户进程空间有消耗，Lighttpd 1.5 的 AIO(异步I/O) 读取文件到用户内存导致效率也比较低下。</p>
<p>但为何我们访问优酷会如此流畅，与土豆相比优酷的视频加载速度略胜一筹？这个要归功于优酷建立的比较完善的内容分发网络（CDN），它通过多种方式保证分布在全国各地的用户进行就近访问——用户点击视频请求后，优酷网将根据用户所处地区位置，将离用户最近、服务状况最好的视频服务器地址传送给用户，从而保证用户可以得到快速的视频体验。这就是CDN带来的优势，就近访问，有关CDN的更多内容，请大家Google一下。</p>
<p>转载地址：<a href="http://www.itivy.com/ivy/archive/2011/8/13/the-architecture-of-youku.html">http://www.itivy.com/ivy/archive/2011/8/13/the-architecture-of-youku.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.liguosong.com/2013/07/18/%e4%bc%98%e9%85%b7%e7%bd%91%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter网站架构学习笔记(转载)</title>
		<link>http://www.liguosong.com/2013/07/18/twitter%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/</link>
		<comments>http://www.liguosong.com/2013/07/18/twitter%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/#comments</comments>
		<pubDate>Thu, 18 Jul 2013 12:59:47 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[网站架构]]></category>

		<guid isPermaLink="false">http://www.liguosong.com/?p=149</guid>
		<description><![CDATA[作为140个字的缔造者，twitter太简单了，又太复杂了，简单是因为仅仅用140个字居然使有几次世界性事件的 [...]]]></description>
				<content:encoded><![CDATA[<p>作为140个字的缔造者，twitter太简单了，又太复杂了，简单是因为仅仅用140个字居然使有几次世界性事件的传播速度超过任何媒体，复杂是因为要为2亿用户提供这看似简单的140个字的服务，这真的是因为简单，所以复杂。可是比较遗憾的是目前在中国大陆twitter是无法访问的，但作为一个爱好架构的程序猿，这道墙是必须得翻的，墙外的世界更精彩。今天就结合网络上的一些资料，来浅谈一下我对twitter网站架构的学习体会，希望给路过的朋友一点启示&#8230;&#8230;.<span id="more-149"></span></p>
<p><strong>一、twitter网站基本情况概览</strong></p>
<ol>
<li>截至2011年4月，twitter的注册用户约为1.75亿，并以每天300000的新用户注册数增长，但是其真正的活跃用户远远小于这个数目，大部分注册用户都是没有关注者或没有关注别人的，这也是与facebook的6亿活跃用户不能相提并论的。</li>
<li>twitter每月有180万独立访问用户数，并且75%的流量来自twitter.com以外的网站。每天通过API有30亿次请求，每天平均产生5500次tweet，37%活跃用户为手机用户，约60%的tweet来自第三方的应用。</li>
<li>平台：Ruby on Rails 、Erlang 、MySQL 、Mongrel 、Munin 、Nagios 、Google Analytics 、AWStats 、Memcached</li>
</ol>
<p>下图是twitter的整体架构设计图：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110814001359_0919.jpg"><img class="alignnone size-full wp-image-154" alt="20110814001359_0919" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110814001359_0919.jpg" width="666" height="446" /></a></p>
<p>&nbsp;</p>
<p><strong>二、twitter的平台</strong></p>
<p>twitter平台大致由twitter.com、手机以及第三方应用构成，如下图所示：</p>
<p><a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110814001910_5390.jpg"><img class="alignnone size-full wp-image-155" alt="20110814001910_5390" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110814001910_5390.jpg" width="643" height="416" /></a></p>
<p>&nbsp;</p>
<p>其中流量主要以手机和第三方为主要来源。</p>
<ul>
<li>Ruby on Rails：web应用程序的框架</li>
<li>Erlang：通用的面向并发的编程语言，开源项目地址：http://www.erlang.org/</li>
<li>AWStats：实时日志分析系统：开源项目地址：http://awstats.sourceforge.net/</li>
<li>Memcached：分布式内存缓存组建</li>
<li>Starling：Ruby开发的轻量级消息队列</li>
<li>Varnish：高性能开源HTTP加速器</li>
<li>Kestrel：scala编写的消息中间件，开源项目地址：http://github.com/robey/kestrel</li>
<li>Comet Server：Comet是一种ajax长连接技术，利用Comet可以实现服务器主动向web浏览器推送数据，从而避免客户端的轮询带来的性能损失。</li>
<li>libmemcached：一个memcached客户端</li>
<li>使用mysql数据库服务器</li>
<li>Mongrel：Ruby的http服务器，专门应用于rails，开源项目地址：http://rubyforge.org/projects/mongrel/</li>
<li>Munin：服务端监控程序，项目地址：http://munin-monitoring.org/</li>
<li>Nagios：网络监控系统，项目地址：http://www.nagios.org/</li>
</ul>
<p><strong>三、缓存</strong></p>
<p>讲着讲着就又说到缓存了，确实，缓存在大型web项目中起到了举足轻重的作用，毕竟数据越靠近CPU存取速度越快。下图是twitter的缓存架构图：<a href="http://www.liguosong.com/wp-content/uploads/2013/07/20110814000909_9086.png"><img class="alignnone size-full wp-image-153" alt="20110814000909_9086" src="http://www.liguosong.com/wp-content/uploads/2013/07/20110814000909_9086.png" width="708" height="738" /></a></p>
<p>大量使用memcached作缓存</p>
<ul>
<li>例如，如果获得一个count非常慢，你可以将count在1毫秒内扔入memcached</li>
<li>获取朋友的状态是很复杂的，这有安全等其他问题，所以朋友的状态更新后扔在缓存里而不是做一个查询。不会接触到数据库</li>
<li>ActiveRecord对象很大所以没有被缓存。Twitter将critical的属性存储在一个哈希里并且当访问时迟加载</li>
<li>90%的请求为API请求。所以在前端不做任何page和fragment缓存。页面非常时间敏感所以效率不高，但Twitter缓存了API请求</li>
</ul>
<p>在memcached缓存策略中，又有所改进，如下所述：</p>
<p>1、创建一个直写式向量缓存Vector Cache，包含了一个tweet ID的数组，tweet ID是序列化的64位整数，命中率是99%</p>
<p>2、加入一个直写式行缓存Row Cache，它包含了数据库记录：用户和tweets。这一缓存有着95%的命中率。</p>
<p>3、引入了一个直读式的碎片缓存Fragmeng Cache，它包含了通过API客户端访问到的sweets序列化版本，这些sweets可以被打包成json、xml或者Atom格式，同样也有着95%的命中率。</p>
<p>4、为页面缓存创建一个单独的缓存池Page Cache。该页面缓存池使用了一个分代的键模式，而不是直接的实效。</p>
<p><strong>四、消息队列</strong></p>
<ul>
<li>大量使用消息。生产者生产消息并放入队列，然后分发给消费者。Twitter主要的功能是作为不同形式(SMS，Web，IM等等)之间的消息桥</li>
<li>使用DRb，这意味着分布式Ruby。有一个库允许你通过TCP/IP从远程Ruby对象发送和接收消息，但是它有点脆弱</li>
<li>移到Rinda，它是使用tuplespace模型的一个分享队列，但是队列是持久的，当失败时消息会丢失</li>
<li>尝试了Erlang</li>
<li>移到Starling，用Ruby写的一个分布式队列</li>
<li>分布式队列通过将它们写入硬盘用来挽救系统崩溃。其他大型网站也使用这种简单的方式</li>
</ul>
<p><strong>五、总结</strong></p>
<p>1、数据库一定要进行合理索引</p>
<p>2、要尽可能快的认知你的系统，这就要你能灵活地运用各种工具了</p>
<p>3、缓存，缓存，还是缓存，缓存一切可以缓存的，让你的应用飞起来。</p>
<p>转载地址：<a href="http://www.itivy.com/ivy/archive/2011/8/14/the-architecture-of-twitter.html">http://www.itivy.com/ivy/archive/2011/8/14/the-architecture-of-twitter.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.liguosong.com/2013/07/18/twitter%e7%bd%91%e7%ab%99%e6%9e%b6%e6%9e%84%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0%e8%bd%ac%e8%bd%bd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
