豆瓣的基础架构

本文根据InfoQ中文站对豆瓣洪强宁(@hongqn)的沟通交流整理而成。洪强宁介绍了豆瓣的架构和组件,并分享了豆瓣基础平台部的一些团队经验。文中截图来自洪强宁在2013年CTO俱乐部中的分享。

嘉宾介绍

洪强宁,豆瓣首席架构师。豆瓣第一位全职员工。清华毕业后,洪强宁一直做嵌入式系统。在2002年开始接触Python语言,从硬件工程师变为软件工程师,对一种语言在计算机底层如何工作有深入的理解。

架构



豆瓣...

阅读全文→


smarteng 发布于 2014-04-22 10:22

web集群session同步方法

网站在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是登录状态。所以本文就在网站建设中根据这种情况给出三种不同的集群方法来解决这个问题:

一,利用数据库同步session

1,用一个低端电脑建个数据库专门存放web服务器的session,或者,把这个专门...

阅读全文→

smarteng 发布于 2013-03-09 15:15

数据库分表策略

 1  垂直划分:

将数据表中的某些字段提出,组成新的数据表。“将群组id,专辑id,音乐id提出”,组成gzm数据表,而将“群组,专辑,音乐的详细信息单独放在其他数据表中”。在求取索引、关系时,操作数据库效率更高。

2  水平划分:

2.1物理上的水平切分:即将数据分配到不同的db服务器上。降低单点机器的负载。

2.2逻辑上的水平划分:将数据分到同一数据库的不同的数据表。多...

阅读全文→


smarteng 发布于 2012-09-06 09:31

缓存设计的一些思考

互联网架构中缓存无处不在,某厂牛人曾经说过:”缓存就像清凉油,哪里不舒服,抹一下就好了”。高品质的存储容量小,价格高;低品质存储容量大,价格低,缓存的目的就在于”扩充”高品质存储的容量。本文探讨缓存相关的一些问题。

LRU替换算法

缓存的技术点包括内存管理和替换算法。LRU是使用最多的替换算法,每次淘汰最久没有使用的元素。LRU缓存实现分为两个部分:Hash表和LRU链表,Hash表用于查找缓存中的元...

阅读全文→


smarteng 发布于 2011-06-22 09:21

大型网站架构演变和知识体系

大型网站架构演变和知识体系,大型网站架构真是一门学问,下面是网上的文章,搜集而来,以备后忘。

阅读全文→

smarteng 发布于 2009-12-06 17:47

注重实效的程序员 | 程序员修炼之道

注重实效的程序员 | 程序员修炼之道
care about your craft 
除非你在乎能否漂亮地开发出软件,否则其它事情都是没有意义的。

阅读全文→

smarteng 发布于 2009-10-28 11:05

多memcached 和 mysql 主从 环境下PHP开发: 代码详解

<?php

$memcached = array(  //用memcached 的 多 进程模拟 多台memcached 服务器   
 cn     en   为  内存服务器名

     'cn'=>array('192.168.254.144',11211),

     'en'=>array('192.168.254.144',11212)

     );

$mysql    = array( // mysql 的主从 我的环境是 : xp 主    linux 从  mysql 5  php5

     'master'=>array('192.168.254.213','root','1','mydz'),

     'slave_1'=>array('192.168.254.144','root','1','mydz')  //可以灵活添加多台从服务器

     );

?>

[break]
复制代码服务器配置文件: 十分方便的 切换主从.  当主换了  从可以迅速切换为主.  支持 多从服务器   . <?php

class Memcached

{

private $mem;

public $pflag=''; // memcached pconnect tag

private function memConnect($serkey){

  require 'config.php';

  $server = $memcached;

  $this->mem = new Memcache;

  $link = !$this->pflag ? 'connect' : 'pconnect' ;

  $this->mem->$link($server[$serkey][0],$server[$serkey][1]) or $this->errordie('memcached connect error');

 

}

 

public function set($ser_key,$values,$flag='',$expire=''){

  $this->memConnect($this->tag($ser_key));

  if($this->mem->set($ser_key,$values,$flag,$expire)) return true;

  else return false;

}

 

public function get($ser_key){

  $this->memConnect($this->tag($ser_key));

  if($var=$this->mem->get($ser_key)) return $var;

  else return false;

}

private function tag($ser_key){

  $tag=explode('_',$ser_key);

  return $tag[0];

}

private function errordie($errmsg){

  die($errmsg);

}

}

?>

复制代码简单的封装了 memcached  的操作.

在memcached 的多服务器上.  我的实现思路是这样的:   在把信息添加到 内存服务器的时候.我选择了手工设置添加到那个服务器.而不用传统的根据ID自动分配.
这样可以更灵活点. 

以内存服务器名 为表示   比如 存  $arr 这个信息到  en 这台 内存服务器 我就这样写   $mem->set('en_'.$arr);    明白了吧 <?php

class Mysql

{

private   $mysqlmaster;

private   $myssqlslave;

private static $auid=0;

public function __construct(){

  require 'config.php';

  $msg = $mysql;

 

  $this->mysqlmaster = new mysqli($msg['master'][0],$msg['master'][1],$msg['master'][2],$msg['master'][3]); //master mysql

   $this->mysqlslave  = $this->autotranscat($msg); // slave mysql

 

  if(mysqli_connect_errno()){

   printf("Connect failed: %s\n",mysqli_connect_error());

   exit();

  }

  if(!$this->mysqlmaster->set_charset("latin1") && !$this->mysqlslave->set_charset("latin1")){

   exit("set charset error");

  }

}

 

private function autotranscat($mysql){

  session_start();

  $_SESSION['SID']!=0 || $_SESSION['SID']=0   ;

  if($_SESSION['SID'] >=count($mysql)-1) $_SESSION['SID'] = 1;

  else $_SESSION['SID']++;

  $key = 'slave_'.$_SESSION['SID'];

  echo($_SESSION['SID']);

  return new mysqli($mysql[$key][0],$mysql[$key][1],$mysql[$key][2],$mysql[$key][3]);

}

 

public function mquery($sql){ //insert  update

  if(!$this->mysqlmaster->query($sql)){

   return false;

  }

}

 

public function squery($sql){

  if($result=$this->mysqlslave->query($sql)){

   return $result;

  }else{

   return false;

  };

}

public function fetArray($sql){

  if($result=$this->squery($sql)){

   while($row=$result->fetch_array(MYSQLI_ASSOC)){

    $resultraa[] = $row;

   };

   return $resultraa;

  }

}

}

?>

复制代码这个是 mysqli 的封装.  也就是   读  从  写 主  的操作的封装. <?php

require 'init.php';

$mem = new Memcached;

/* $mem->set('en_xx','bucuo');

echo($mem->get('en_xx'));

$mem->set('cn_jjyy','wokao');

echo($mem->get('cn_jjyy'));

*/

$sq = new Mysql;

$sql = "insert into mybb(pid) values(200)";

$mdsql = md5($sql);

if(!$result=$mem->get('cn_'.$mdsql)){

  $sq->mquery("insert into mybb(pid) values(200)"); //插入到主mysql

  $result = $sq->fetArray("select * from mybb"); //查询 是 从mysql

  foreach($result as $var){

   echo $var['pid'];

  }

  $mem->set('cn_'.$mdsql,$result); //添加到 名为 cn 的 memcached 服务器 

}else{

  foreach($result as $var){

   echo $var['pid'];

  }

}

?>
 


smarteng 发布于 2009-10-16 21:56

浅析MVC设计思想

一、MVC设计思想
  MVC英文即Model-View-Controller,即把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层。
  视图(View)代表用户交互界面,对于Web应用来说,可以概括为HTML界面,但有可能为 XHTML、XML和Applet。随着应用的复杂性和规模性,界面的处理也变得具有挑战性。一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理。业务流程的处理交予模型(Model)处理。比如一个订单的视图只接受来自模型的数据并显示给用户,以及将用户界面的输入数据和请求传递给控制和模型。[break]
  模型(Model):就是业务流程/状态的处理以及业务规则的制定。业务流程的处理过程对其它层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心。目前流行的EJB模型就是一个典型的应用例子,它从应用技术实现的角度对模型做了进一步的划分,以便充分利用现有的组件,但它不能作为应用设计模型的框架。它仅仅告诉你按这种模型设计就可以利用某些技术组件,从而减少了技术上的困难。对一个开发者来说,就可以专注于业务模型的设计。MVC设计模式告诉我们,把应用的模型按一定的规则抽取出来,抽取的层次很重要,这也是判断开发人员是否优秀的设计依据。抽象与具体不能隔得太远,也不能太近。MVC并没有提供模型的设计方法,而只告诉你应该组织管理这些模型,以便于模型的重构和提高重用性。我们可以用对象编程来做比喻,MVC定义了一个顶级类,告诉它的子类你只能做这些,但没法限制你能做这些。这点对编程的开发人员非常重要。
  业务模型还有一个很重要的模型那就是数据模型。数据模型主要指实体对象的数据 保存(持续化)。比如将一张订单保存到数据库,从数据库获取订单。我们可以将这个模型单独列出,所有有关数据库的操作只限制在该模型中。
  控制(Controller)可以理解为从用户接收请求, 将模型与视图匹配在一起,共同完成用户的请求。划分控制层的作用也很明显,它清楚地告诉你,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。例如,用户点击一个连接,控制层接受请求后, 并不处理业务信息,它只把用户的信息传递给模型,告诉模型做什么,选择符合要求的视图返回给用户。因此,一个模型可能对应多个视图,一个视图可能对应多个模型。
  模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其它依赖于这些数据的视图都应反映到这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。这实际上是一种模型的变化-传播机制。


smarteng 发布于 2009-10-16 17:14