- 浏览: 118150 次
- 性别:
- 来自: 北京
文章分类
最新评论
看到一个关于人人架构中的问题,觉得很不错,分享给大家... 与很多大型的网站一样,人人网的系统全部是由开源软件构建的。使用Nginx做前端接入,resin做容器,Memcached做通用cache,MySQL做数据库,使用Linux操作系统。 在上述结构系统中,数据库的性能往往成为系统瓶颈。人人网在发展的过程中不断重构,改变最大的就是数据库部分。大概的步骤是“优化SQL”,“业务拆分”,“垂直拆分”和“水平拆分”几个阶段,关于数据库优化的细节将来再引用到这里。 增加中间层可以在不增加服务器数量的前提下,提高服务的整体性能,并且提高系统的可扩展性。这里简要列举一些使用中间层服务优化的效果。 用户的个人信息数据,目前的写操作500次/秒,读操作2万次/秒。这些数据分布在数十个数据表中,如果用数据库做10次主键查询,需要的时间将会非常可观。中间层的缓存服务把这个性能稳定在了99.9%的请求时间小于20ms。 聚合的页面在SNS中是访问量最大的部分。首页集成的功能多达17个模块,这些模块之间的关系相对独立。为了快速的把这些数据集合在一起,就需要迅速获取数据。 众多的resin服务器之间,如何共享用户身份验证的结果,在各种session共享机制中,我们的方案是使用中间层服务来集中存储的。 问题篇只是开端,接下来的“求解篇”将会分析人人网中间层的主要应用场景。“实践篇”将会举例一个典型的中间层服务。 人人网中间层:求解篇 为了提高性能,在人人网的技术结构中,在数据库和页面之间,有中间层。中间层高性能的基础是用内存代替磁盘。 数据库系统的最大瓶颈在磁盘IO,大量的小数据请求不是磁盘的强项。人人网中间层服务就是利用了内存代替硬盘的方法来提高整体性能。有了这层服务以后,以前的数据库关联查询被提前计算并缓存,需要访问时直接获取。 用Ice解决了通信和部署的问题后,中间层服务就是核心的数据结构管理。概括的说,就是灵活变化,保证速度。下面列举若干使用了中间层服务的情况 在人人网的好友页,有很多排序方式可以显示好友列表。每种列表都是从一个按ID排序的服务中获取的,再经过排序,缓存在各个顺序的列表中。 在很多列表页面,都会显示“在线标志”,这个标志是冗余在各个列表的缓存当中,定期刷新的。这些需要和cache一起实现的业务逻辑,在人人网中间层当中非常普遍。 我们用了一个bit保存用户的激活状态。200M内存可以保存全部int范围的状态。并且查询和更新速度飞快。 人人网中间层:实践篇 之前的问题篇和求解篇描述了人人网在发展过程中遇到的问题,并且介绍了我们采用中间层来提高性能的解决方案。今天的实践篇将通过一个例子来实现一个中间层服务。 下面的代码都在这个位置保存:http://gitorious.org/renren/bitserver。 定义接口如下: 这个BitServer.ice文件,通过slice2cpp命令编译成为服务端的Skeleton文件: 有了上面生成的服务端文件后,就可以实现我们自己的业务功能了。 #define SIZE_OF_BIT 2147483647 namespace renren class BitServerI : virtual public BitServer virtual bool get(::Ice::Int, virtual ::Ice::BoolSeq gets(const ::Ice::IntSeq&, virtual ::renren::BitSegment getSegment(::Ice::Int, } #endif void bool ::Ice::BoolSeq ::renren::BitSegment 我们使用Java作为客户端,首先用slice2java工具生成Java的Proxy类。 然后自己实现客户端代码: public BitServerAdapter(String endpoints) { public void initialize() { public boolean get(int id) { public static void main(String[] args) { 完成了代码,来测试一下性能吧。 再启动客户端 在客户端调用增加循环50000次,单线程平均每秒处理一万次。 在多线程的环境下,单个服务器每秒可处理的请求8万次左右,已经超过了目前的需要。 来自:http://ugc.renren.com/2009/12/28/renren-ice-problem/ 由开源软件组成的系统
除了上述的部分外,人人网还有一个与众不同的中间层。中间层以服务的形式存在,位于MySQL和resin中间,提供高并发低成本的数据访问层。数据库的压力
经过优化后的数据库,单台可以承担每秒3000次的主键查询。再提高性能的优化,我们采用的方案是使用中间层。性能目标
实时更新的数据
判断好友关系,读操作900次/秒。这个操作现在使用6G内存存储了所有的好友关系,在2ms内返回任意两人的好友关系。
关联查询,仅好友列表就有1300次/秒。如果使用关联查询,数据库需要同步很多无用的字段。现在只需要两次内存请求,并且衍生出很多种类的排序。大量聚合的访问
我们对整体技术框架的要求是,关键页面执行时间要在100ms以内。Session同步
待续
用内存代替磁盘
通用的Memcached缓存方案也有些不足,数据不能自己变化,也不能部分变化。于是人人网选择了自己实现缓存的方式。
在自己实现缓存的过程中,管理内存相对容易,通信协议是比较复杂的部分,我们在这方面选择了开源的Ice通信框架(http://www.zeroc.com)来完成繁琐的工作,至今它都工作的很好。
Ice通信框架在人人网完成了两件事,通信和定位。客户端通过IceGrid组件定位到需要的服务地址,将请求发送到中间层服务,中间层服务将结果返回。客户端只需要知道一个地址就可以找到所有的服务;同时,众多服务也可以在不同的服务器之间随意迁移。在现在的人人网有超过500个Ice写成的中间层服务在运行。定制的内存数据
一份数据 多种排序
随时间变化的数据
特殊类型
接下来的实践篇将会用这个为例子展示中间层的实现。
这个服务要达到的目的是快速的查询用户是否有效,数据将要使用bitset保存在内存中,每个用户一位,仅保存正整数约21亿,占用内存256M。开始编码
接口定义
module renren {
struct BitSegment {
int begin;
int end;
Ice::ByteSeq data;
};
interface BitServer {
bool get(int offset);
Ice::BoolSeq gets(Ice::IntSeq offsets);
BitSegment getSegment(int begin, int end);
};
};
服务端
BitServerI.h和BitServerI.cpp,暂时只是实现了单个get的接口。
#define __BitServerI_h__#include <BitServer.h>
#include <bitset>
{
{
public:
void initialize();
const Ice::Current&);
const Ice::Current&);
::Ice::Int,
const Ice::Current&);
private:
std::bitset<SIZE_OF_BIT> bits_;
};
#include <Ice/Ice.h>int main(int argc, char** argv) {
int status = 0;
Ice::CommunicatorPtr ic;
try{
ic = Ice::initialize(argc, argv);
Ice::ObjectAdapterPtr adapter = ic->createObjectAdapter(“BitServer”);
renren::BitServerI* obj = new renren::BitServerI;
obj->initialize();
adapter->add(obj, ic->stringToIdentity(“BitServer”));
adapter->activate();
ic->waitForShutdown();
} catch (const Ice::Exception& e) {
std::cerr << e << std::endl;
status = 1;
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
status = 1;
} catch (…) {
std::cerr << “unknown exception” << std::endl;
status = 1;
}
if (ic) {
try {
ic->destroy();
} catch (const Ice::Exception& e) {
std::cerr << e << std::endl;
status = 1;
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
status = 1;
} catch (…) {
std::cerr << “unknown exception” << std::endl;
status = 1;
}
}
return status;
}
renren::BitServerI::initialize() {
for (int i=0; i<0xFFFFF;i=i+2) {
bits_[i]=true;
}
}
renren::BitServerI::get(::Ice::Int offset,
const Ice::Current& current)
{
if(offset < 0) return false;
return bits_[offset];
}
renren::BitServerI::gets(const ::Ice::IntSeq& offsets,
const Ice::Current& current)
{
return ::Ice::BoolSeq();
}
renren::BitServerI::getSegment(::Ice::Int begin,
::Ice::Int end,
const Ice::Current& current)
{
return ::renren::BitSegment();
}客户端
private final String endpoints_;
private Ice.Communicator ic_;
private renren.BitServerPrx prx_;
this.endpoints_ = endpoints;
}
ic_ = Ice.Util.initialize();
prx_ = renren.BitServerPrxHelper.uncheckedCast(ic_.stringToProxy(endpoints_));
}
return prx_.get(id);
}
BitServerAdapter adapter = new BitServerAdapter(args[0]);
adapter.initialize();
boolean ret = adapter.get(Integer.valueOf(args[1]));
System.out.println(ret);
System.exit(0);
}
}性能测试
首先启动服务器
renren.BitServerAdapter “BitServer:default -p 10000” 1022
发表评论
-
高并发高负载网站的系统架构浅析
2012-01-18 18:22 3184大型网站,比如门户 ... -
架构设计之分布式缓存
2012-01-16 18:29 16501:前言 我们在开发系统的过程中,缓存是个有用的模块。 ... -
struts2主要属性配置含义
2011-11-22 09:55 962struts.tag.altSyntax 该属性指定是否 ... -
从 iBatis 到 MyBatis
2011-10-25 11:31 1066对于从事 Java EE 的开发人员来说,iBat ... -
高并发高流量网站架构设计
2011-09-25 21:53 1103今天看到一片相关的文章,觉得不错,以供分享。尽管讲的不是很透彻 ... -
Hibernate性能优化要点
2011-09-22 19:04 911Hibernate性能优化要点: 1.尽量使用man ... -
HACMP全攻略之概念篇
2011-09-22 16:35 1747HACMP全攻略之概念篇 ... -
数据权限管理方案探讨
2011-09-22 11:56 1815Ralasafe开源有段时间了,大约有2个月了。根据社区的 ... -
Hibernate过滤器使用窍门
2011-09-22 11:16 1109Hibernate3新增了对某个类或者集合使用预先定义的Hib ... -
软件架构师应该知道的97件事
2011-09-13 20:05 677软件架构师是IT 行业里 ...
相关推荐
同时,开发了基于ICE的中间层,并对MySQL进行了垂直分区。2008年,人人网进一步采用开放API和SOA(面向服务架构),将MySQL集群进行水平分区,加强监控和安全性,并引入DFS和龙存架构,以提升存储能力。 到了2009年...
同时,他们也使用了开源的ICE框架,以构建完整的RPC(远程过程调用)架构,实现缓存和其他中间层功能。 然而,服务化并非一帆风顺。自建的REST框架无法满足跨语言服务调用,而开源的ICE虽然提供了全面的解决方案,...
同时,他们也使用了开源的ICE框架,以实现完整的RPC架构和缓存等中间层功能,服务于如新鲜事儿等系统。\n\n**异构服务总线的挑战**\n\n在服务化过程中,人人网遇到了异构服务总线的问题。自建REST框架虽然灵活,但...
### 人人网数据服务平台:基于日志分析的数据系统架构 #### 背景与挑战 在互联网行业,数据成为驱动业务发展的核心力量。人人网,作为中国早期的社交网络服务提供商,面临着海量用户数据的管理和分析挑战。传统的...
6. 架构层:架构层包含了多厂商的计算、存储和网络设备,硬件设备在此层是必不可少的。 7. SAS:串行附加存储(SAS)采用串行技术以提高传输速度,并通过改进内部连接线节省空间。 8. 虚拟化技术:虚拟化技术通过...
6. **架构层**:在云计算架构中,架构层包含多厂商的计算、存储和网络设备,是硬件设备的基础。 7. **SAS**:Serial Attached SCSI(SAS)采用串行技术,提供高速传输并改善内部空间。 8. **虚拟化技术**:虚拟化...
管理员进入登录后,可对帐户进行管理,包括添加管理员帐户、修改管理员帐户、删除管理员帐户和对帐户进行权限设置。 博客用户通过前台登录后,可对自己的博客空间进行管理,包括发布自己的网络日志、收藏个人图片...
在Web 2.0时代,SNS网站如Facebook、MySpace在全球范围内取得了巨大成功,而在中国,有校内网(现已更名人人网)和开心网等代表。随着市场需求的多样化,SNS也逐渐分化,出现了商务SNS,如LinkedIn和若邻网(wealink...
它为学生提供参与社交活动的广阔空间,像现在的一些"人人网"啊,它使学生能实现"海内存知己,天涯若比邻";它还丰富了学生的生活,摆脱了学生读书生活的单调。看来网络世界的利用好了,还能造福世界。 七五网络安全...
该部分提供了录播系统的基本架构示意图,包括前端采集设备、中间传输层和后端存储处理服务器等关键组件。 ##### 4.3 高清全自动录播主机 高清全自动录播主机是系统的核心部件之一,负责录制、存储和管理视频资源。...
同时,这种模式鼓励人人参与,形成自由快递人网络,减少了中间环节,降低了时间成本。 “互联网+”模式还促进了配送服务的标准化和规范化,有利于市场优胜劣汰,推动物流行业的健康发展。通过全程联网和智能匹配,...
2. 外部配套:附近有长沙第二十中、裕湘学校等教育资源,新一佳超市、人人乐超市、步步高百货商场等商业设施,以及世贸希尔顿酒店(在建)等星级酒店,以及多家银行和医疗机构。 户型分析:项目主要以95-142平方米...