构建一个高效无单点故障的分布式session服务

fmms 12年前
     <p>本文来自:<a href="/misc/goto?guid=4959500779655947643" rel="nofollow" target="_blank">http://www.cellphp.com/article-read-opensource-32-php-session-distributed-redis.html</a></p>    <p>自从PHP问世以来,以其简单的语法丰富的函数和扩展风靡WEB开发界。但是其简单的功能也是PHP致命点。现在的高访问量高并发量使单机PHP项 目无法承受了。所以也出现各种各样的分布式存储。今儿咱讲讲怎么构建一个高效的无单点故障的分布式session服务。 咱可不是标题党,内容和标题绝对吻合。</p>    <p>现在PHP项目分布式session 一般都是 memcached+ client consistent hash。这个解决方案优点是简单。缺点也是N多的。 具体的缺点,可参见 Timyang的 文章 <br /> <a href="/misc/goto?guid=4959500779753350071" rel="nofollow" target="_blank">http://timyang.net/architecture/consistent-hashing-practice/</a></p>    <p><img alt="构建一个高效无单点故障的分布式session服务" src="https://simg.open-open.com/show/b44c78eff41765a049fa8ed234696f30.png" width="600" height="271" /></p>    <p>现在咱来说说咱的分布式session 架构,上面这个图这个架构的示意图, 下面是该架构重要的三个部分的说明.</p>    <p>1.  为Web Server集群。 每台机器由Nginx+PHP+eAccelerator组成</p>    <p><span style="font-size:x-small;">         <span style="font-size:14px;">nginx 和PHP 是什么我就不多说了。</span><br />          <span style="color:#e53333;font-size:14px;">eAccelerator 是本session架构的点睛之处, eAccelerator不仅是个opcode缓存器.也提供基于共享内存的key-value的存储。共享内存方式的数据存取比socket的 memcached 快多了。 在这里eAccelerator作为 远程session服务的一个本地缓存区。大量减少直接从 session 集群读取数据的压力 </span></span></p>    <p><span style="font-size:x-small;"><span style="font-size:14px;">2.  session proxy</span></span></p>    <p><span style="font-size:x-small;"><span style="font-size:14px;">        session proxy是基于linux + C + epoll实现的session代理服务器,具有连接池和后端服务器健康监控等功能。 session data 采用我自己研究的session hash法分布数据。 session hash是扩展于传统的 hash() mod n的方式。hash() mod n优点是直接定位快。缺点就是增减服务器的时候,产生的灾难性的数据变动。</span></span></p>    <p><span style="font-size:x-small;"><span style="font-size:14px;">       <span style="color:#e53333;">session hash 还是采用最快的"</span><span style="color:#e53333;">hash() mod n"</span></span></span><span style="font-size:x-small;"><span style="font-size:14px;"><span style="color:#e53333;">的方式来快速进行数据分布</span></span></span><span style="font-size:x-small;"><span style="color:#e53333;font-size:14px;"><span style="color:#e53333;">。</span> 但是服务器动态增减或者服务器故障采用新的处理方式。 下面具体讲解一下以上这些情况怎么解决。</span></span></p>    <p><span style="font-size:x-small;"><span style="color:#e53333;font-size:14px;">      服务器故障:比如 有 A、B、C三台session服务器。C 服务器挂了。 就会根据A、B服务器的权重选出一台服务器,充当C服务器。还是组成虚拟的三台服务器(就是无论几台服务器挂了。逻辑上都还有三台服务器的)。 然后由session proxy告知PHP 应用按需重建session数据。 因为</span></span><span style="color:#e53333;">前端的eAccelerator已经挡住大多数的session数据请求。所以这个session data 重建并不会带来太大的session集群震荡</span></p>    <p><span style="color:#e53333;">    <span style="font-size:14px;">服务器的动态 增减:这个情景是容易碰到的事情。在这里引用了个动态cursor和timeout的概念。动态游标简单的来说就是我原先有三台服务器,现在加两台服务 器。那就是五台服务器了。 我取session数据的时候。先"hash mod 3",取不到数据,我再"hash mod 5"的方式去读取。 看到这里有人就会说了。你这样一次操作得读取两次效率不行啊。所以timeout的概念出现了。因为session 数据是暂时的。比如我登录一个论坛,我看几个帖子觉的没意思。我就把浏览器关了。这样就代表着一个session数据销毁。所以说我们设置个20分钟的 timeout。在这20分钟内都是使用两次mod的方式去读取。超过20分钟的session data。就要对该session data进行重建(使用"hash mod 5"的方式服务器定位)。而且只mod 一次读取。</span></span></p>    <p> </p>    <p><span style="font-size:14px;">3. session data store</span></p>    <p><span style="font-size:14px;">        session data store实际上是采用redis来当session 数据存储。</span></p>    <p> </p>    <p><span style="font-size:14px;"><img alt="构建一个高效无单点故障的分布式session服务" src="https://simg.open-open.com/show/4fc73217df78eee5ab79bdc4cc378acd.png" width="519" height="814" /></span></p>    <p><span style="font-size:14px;"><img alt="构建一个高效无单点故障的分布式session服务" src="https://simg.open-open.com/show/184d8cb44d5cc5cff327646fd331ffa4.png" width="633" height="863" /></span></p>    <p><strong><span style="font-size:18px;"> 总结</span></strong></p>      刚才也说过eAccelerator 是本session架构的点睛之处.确实也是,eAccelerator 的session缓存已经承担了相当一部分的session数据访问。所以当后端session挂了话。也能够快速的按需重建session数据。还有一 个点睛之处就是优化的hash算法。在传统的"Hash mod n"基础上, 引用了虚拟服务器和动态cursor的概念。研究出适合分布式session服务器的一种高效hash分布算法,实际上session proxy没有session位置存储,所以session proxy可以是多台。此文的不成熟之处,望请大家多多提出来,我好改正。谢谢大家