℃冻番茄's Blog

Feed Rss

http://code.google.com/p/redis/downloads/detail?name=redis-2.0.4.tar.gz

安装及启动方法非常的简单,目前非常稳定,性能强大挺适合部署在生产环境中使用

准备部署到joyjin网

安装方法

tar xvzf redis-2.0.4.tar.gz
cd  redis-2.0.4
make
mkdir /home/redis
cp redis-server  /home/redis
cp redis-benchmark  /home/redis
cp redis-cli  /home/redis
cp redis.conf  /home/redis
cd  /home/redis

启动

./redis-server redis.conf

进入命令交互模式

两种

1:   ./redis-cli

2:   telnet 127.0.0.1 6379       (ip接端口)

Connecting, Creating and using a DB, Create a Table / Collection

$link = new Mongo();       $link = mysql_connect($host, $user, $pass, 1) or die(“Could not connect to: {$host}.”);

$db = $link->testdb;         $sql = “CREATE DATABASE `$db`”; mysql_select_db($db`,$link);

$col = $db->user;               $sql = “CREATE TABLE ‘user’…;      mysql_query($sql,$link);

$col->drop();         mysql_query(DROP TABLE `$db`.`$tbl`, $link);

$db->drop();          mysql_query(DROP DATABASE `$db`, $link);

$link->close();       mysql_close($link);

Insert Data

$doc= array(‘login’ => ‘jsmith’, ‘password’ => ‘ 5f4dcc3b5aa765d61d8327deb882cf99′, ‘email’ => ‘jsmith@example.com’);
mysql_query(“INSERT INTO `$tbl` SET `login`=’jsmith’,`password`=’5f4dcc3b5aa765d61d8327deb882cf99′,`email`=’jsmith@example.com’”);

$id = $doc['_id'];         $id = mysql_insert_id($link);

Updating Data

$col->update(array(‘_id’ => $id), array(‘$set’ => array(‘password’ => ‘b497dd1a701a33026f7211533620780d’)));

$qry = mysql_query(“UPDATE `$tbl` SET `password` = ‘b497dd1a701a33026f7211533620780d’ WHERE `id` = {$id}”, $link);

Indexing data

$col->ensureIndex(array(“login” => 1), array(“unique” => true, “dropDups” => true));

$qry = mysql_query(“ALTER TABLE `$db`.`$tbl` ADD UNIQUE `login` (`login`)”, $link);

Querying Data

$res = $col->find();                                               SELECT * FROM `$tbl`

$doc = $col->findone(array(‘_id’ => $id));          SELECT * FROM `$tbl` WHERE `id` = {$id}

$res = $col->find()->limit(1);                                SELECT * FROM `$tbl` LIMIT 1

$res = $col->find()->skip(1)->limit(1);                                         SELECT * FROM `$tbl` OFFSET 1 LIMIT 1;

$res = $col->find()->sort(array(‘login’ => -1));                            SELECT * FROM `$tbl` ORDERBY `login` DESC //-1=DESC,1=ASC

$res = $col->find(array(‘age’ => array(‘$lt’ => 30)));                   SELECT * FROM `$tbl` WHERE `age` < 30                 //$lt:<,$gt:>,$gte:>=, $lte:<=, $ne:!=

$doc = $col->find(array(’a’=>’hello’,’b’=>1));                                SELECT * FROM `$tbl` WHERE `a` = ‘hello’ AND `b`=1

$doc = $col->find(array(’a’=>’hello’,’b’=>array(’$gt’=>1)));                  SELECT * FROM `$tbl` WHERE `a` = ‘hello’ AND `b`>=1

$res = $col->find(array(‘age’ => array(‘$gte’ => 20, ‘$lte’ => 50)));              SELECT * FROM `$tbl` WHERE `age` >= 20 AND `age` <= 50

$col->remove(array(‘age’=>24),array(‘justOne’=>true,’safe’=>true));          DELETE FROM `$tbl` WHERE `login` = ‘psmith’

MongoCollection::insert(array $a,array $options)    //$a要插入的数组, $options选项:safe是否返回结果信息,fsync是否直接插入到物理硬盘

db.linlin.find({id:10})                                返回linlin数据集ID=10的数据集

db.linlin.find({id:10}).count()                             返回linlin数据集ID=10的数据总数

db.linlin.find({id:10}).limit(2)                            返回linlin数据集ID=10的数据集从第二条开始的数据集

db.linlin.find({id:10}).skip(8)                    返回linlin数据集ID=10的数据集从0到第八条的数据集

db.linlin.find({id:10}).limit(2).skip(8)      返回linlin数据集ID=1=的数据集从第二条到第八条的数据

db.linlin.find({id:10}).sort()                      返回linlin数据集ID=10的排序数据集

db.linlin.findOne([query])                        返回符合条件的一条数据

db.linlin.getDB()                                       返回此数据集所属的数据库名称

db.linlin.getIndexes()                               返回些数据集的索引信息

db.linlin.group({key:…,initial:…,reduce:…[,cond:...]})

db.linlin.mapReduce(mayFunction,reduceFunction,)

db.linlin.remove(query)                            在数据集中删除一条数据

db.linlin.renameCollection(newName)   重命名些数据集名称

db.linlin.save(obj)                                     往数据集中插入一条数据

db.linlin.stats()                                         返回此数据集的状态

db.linlin.storageSize()                              返回此数据集的存储大小

db.linlin.totalIndexSize()                          返回此数据集的索引文件大小

db.linlin.totalSize()                                   返回些数据集的总大小

db.linlin.update(query,object[,upsert_bool])    在此数据集中更新一条数据

db.linlin.validate()                                    验证此数据集

最近的工作是优化网站的列表缓存

采用的是redis+memcache结构

redis只存文章ID号及逻辑关系 memcache存单篇文章的信息、内容及点击数

redis和memcache采用的都是主动缓存模式,在通常情况下,缓存时间不设时限,并且不主动读取mysql数据库,所有的数据从缓存中读取

列表缓存需求:不同分类及所有分类的文章列表,带分页功能

redis使用lists存储不同的分类列表

例: news_list_1:           表示存放文章cid为1的列表的key,值为id号

new_list_1:2:3:4:5      表示存放文章cid为1,2,3,4,5的全部文章列表的key

压数据:从mysql中按排序要求把这些文章的ID号摄取出来,从底部开始压入按cid命名的lists中

添加新篇文章后,把新的文章id压入最上面,然后从mysql中,按顺序读取这个ID上面有多少篇文章,决定交换多少次的次数n

然后把新的文章ID(因为压在最上页,index为0)与下面的index 一个一个交换值 ,一共交换上面从mysql得到的次数n

修改排序方法同新加。先删除,然后把ID压到最上面,最后把这个ID下沉到指定位置

删除ID就简单了,直接可以使用lists的删除命令,通过value删除

需要使用分页,则主要是使用命令 LRANGE key start end  指定开始的index及结束的index.按分页要求取一段数据

然后把取到这的段ID数组,放入memcache中得到文章的标题等信息,最后在php中组成数组,输出。这样一个列表缓存就搞定了

原理是利用MongoDb的GridFS,伸展性方面交由MongoDb的auto sharding去实现,这里用PHP给MongoDb绑了个S3出来,支持选择文件存储节点,支持文件分目录存储,这样的好处是对于一些受时间影响比较明显的文件,可以按照年月的形式存储,减轻历史包袱。

首先,配置MongoDb GridFS节点信息:

<?php
$s3Config = array(
    'foo' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),
 
    'bar' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),
);

MongoDb的S3绑定:

<?php
/**
 * 统一文件存储
 *
 */
class Api_S3
{
    protected
原理是利用MongoDb的GridFS,伸展性方面交由MongoDb的auto sharding去实现,这里用PHP给MongoDb绑了个S3出来,支持选择文件存储节点,支持文件分目录存储,这样的好处是对于一些受时间影响比较明显的文件,可以按照年月的形式存储,减轻历史包袱。

首先,配置MongoDb GridFS节点信息:
<?php
$s3Config = array(
    'foo' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),

    'bar' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),
);

MongoDb的S3绑定:

___FCKpd___1

文件存入,支持自选节点,自定义目录,自定义文件名,可以自动添加文件类型:

<?php
$s3 = new Api_S3($node, $dir, $s3Config);
$s3->copy($file, array('filename' => $name, 'filetype' => $type));

文件读取,以”http://s3.foobar.com/foo/201005/foobar.jpg”为例,foo映射到节点名,201005映射到目录名,foobar.jpg映射到文件名:

<?php
$s3 = new Api_S3($node, $dir, $s3Config);
$file = $s3->file($name);

Cola_Response::lastModified($file->file['uploadDate']->sec);
Cola_Response::etag($file->file['md5']);

if (isset($file->file['filetype'])) {
    header("Content-Type: {$file->file['filetype']}");
}

echo $file->getBytes();

注意到我们利用了文件的修改时间设置http头的last modified,以及用文件的md5信息设置etag值,这样的好处是可以大大减少带宽使用,当然,你也可以设置expire时间来减少重复请求。

关于性能问题,可以在PHP读取的上一层,加一个Squid之类的反向代理服务,基本上就不会有问题。

本文来自:http://www.fuchaoqun.com/2010/05/s3-on-mongodb-with-php/

node;   protected原理是利用MongoDb的GridFS,伸展性方面交由MongoDb的auto sharding去实现,这里用PHP给MongoDb绑了个S3出来,支持选择文件存储节点,支持文件分目录存储,这样的好处是对于一些受时间影响比较明显的文件,可以按照年月的形式存储,减轻历史包袱。

首先,配置MongoDb GridFS节点信息:

<?php
$s3Config = array(
    'foo' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),

    'bar' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),
);

MongoDb的S3绑定:

___FCKpd___1

文件存入,支持自选节点,自定义目录,自定义文件名,可以自动添加文件类型:

___FCKpd___2

文件读取,以”http://s3.foobar.com/foo/201005/foobar.jpg”为例,foo映射到节点名,201005映射到目录名,foobar.jpg映射到文件名:

___FCKpd___3

注意到我们利用了文件的修改时间设置http头的last modified,以及用文件的md5信息设置etag值,这样的好处是可以大大减少带宽使用,当然,你也可以设置expire时间来减少重复请求。

关于性能问题,可以在PHP读取的上一层,加一个Squid之类的反向代理服务,基本上就不会有问题。

本文来自:http://www.fuchaoqun.com/2010/05/s3-on-mongodb-with-php/

dir;   protected原理是利用MongoDb的GridFS,伸展性方面交由MongoDb的auto sharding去实现,这里用PHP给MongoDb绑了个S3出来,支持选择文件存储节点,支持文件分目录存储,这样的好处是对于一些受时间影响比较明显的文件,可以按照年月的形式存储,减轻历史包袱。

首先,配置MongoDb GridFS节点信息:

<?php
$s3Config = array(
    'foo' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),

    'bar' => array(
        'server' => '127.0.0.1',
        'database' => 'test',
        'user' => 'test',
        'password' => 'foobar',
        'domain' => 'http://s3.foobar.com'
    ),
);

MongoDb的S3绑定:

___FCKpd___1

文件存入,支持自选节点,自定义目录,自定义文件名,可以自动添加文件类型:

___FCKpd___2

文件读取,以”http://s3.foobar.com/foo/201005/foobar.jpg”为例,foo映射到节点名,201005映射到目录名,foobar.jpg映射到文件名:

___FCKpd___3

注意到我们利用了文件的修改时间设置http头的last modified,以及用文件的md5信息设置etag值,这样的好处是可以大大减少带宽使用,当然,你也可以设置expire时间来减少重复请求。

关于性能问题,可以在PHP读取的上一层,加一个Squid之类的反向代理服务,基本上就不会有问题。

public function __construct($node, $dir = null, $config = null)
    {
        $this->_config = $config;
 
        $this->path($node, $dir, false);
    }
 
    /**
     * 设置文件路径
     *
     * @param string $node
     * @param string $dir
     * @return Api_S3
     */
    public function path($node, $dir, $connect = true)
    {
        $this->_node = $node;
        $this->_dir = empty($dir) ? 'fs' : $dir;
 
        if (empty($this->_config[$this->_node])) {
            throw new Cola_Exception('Api_S3: invalidate node');
        }
 
        if ($connect) {
            $this->_gridFS = $this->_gridFS();
        }
 
        return $this;
    }
 
    /**
     * GridFS
     *
     * @return MongDbGridFS
     */
    protected function _gridFS()
    {
        $mongo = new Cola_Com_Mongo($this->_config[$this->_node]);
 
        return $mongo->gridFS($this->_dir);
    }
 
    /**
     * 获得文件句柄
     *
     * @param string $name
     * @return MongoGridFSFile
     */
    public function file($name)
    {
        if (empty($this->_gridFS)) {
            $this->_gridFS = $this->_gridFS();
        }
 
        return $this->_gridFS->findOne(array('filename' => $name));
    }
 
    /**
     * 获得文件内容
     *
     * @param string $name
     */
    public function read($name)
    {
        $file = $this->file($name);
 
        return $file->getBytes();
    }
 
    /**
     * 写入文件
     *
     * @param string $name
     * @param string $data
     * @param array $extra
     * @param boolean $overWrite
     * @return boolean
     */
    public function write($name, $data, $extra = array(), $overWrite = false)
    {
        $extra = (array)$extra + array('filename' => basename($name));
 
        if ($filetype = $this->_type($name)) {
            $extra['filetype'] = $filetype;
        }
 
        if ($this->file($extra['filename'])) {
            if ($overWrite) {
                $this->delete($extra['filename']);
            } else {
                throw new Cola_Exception('Api_S3: file exists');
            }
        }
 
        return $this->_gridFS->storeBytes($data, $extra);
    }
 
    /**
     * 复制系统文件
     *
     * @param string $file
     * @param array $extra
     * @param boolean $overWrite
     * @return boolean
     */
    public function copy($file, $extra = array(), $overWrite = false)
    {
        $extra = (array)$extra + array('filename' => basename($file));
 
        if ($filetype = $this->_type($file)) {
            $extra['filetype'] = $filetype;
        }
 
        if ($this->file($extra['filename'])) {
            if ($overWrite) {
                $this->delete($extra['filename']);
            } else {
                throw new Cola_Exception('Api_S3: file exists');
            }
        }
 
        return $this->_gridFS->storeFile($file, $extra);
    }
 
    /**
     * 删除文件
     *
     * @param string $name
     * @return boolean
     */
    public function delete($name)
    {
        if (empty($this->_gridFS)) {
            $this->_gridFS = $this->_gridFS();
        }
 
        return  $this->_gridFS->remove(array('filename' => $name));
    }
 
    /**
     * 获得文件地址
     *
     * @param string $name
     * @param string $default
     * @return string
     */
    public function getUrl($name, $default = false)
    {
        $data = array(
            'domain' => rtrim($this->_config[$this->_node]['domain'], '/'),
            'path'   => $this->_node . (('fs' == $this->_dir) ? '' : $this->_dir),
            'name'   => $name
        );
        return  implode('/', $data);
    }
 
    /**
     * 设置文件属性
     *
     * @param string $name
     * @param array $attr
     * @return boolean
     */
    public function setAttr($name, $attr)
    {
        if (!$file = $this->file($name)) {
            throw new Cola_Exception('Api_S3: file not exists');
        }
 
        $file->file = $attr + $file->file;
 
        return $this->_gridFS->save($file->file);
    }
 
    /**
     * 获得文件属性
     *
     * @param string $name
     * @return array
     */
    public function getAttr($name)
    {
        $file = $this->file($name);
        return $file->file;
    }
 
    /**
     * 获得文件类型
     *
     * @param string $file
     * @return string
     */
    protected function _type($file)
    {
        return mime_content_type($file);
    }
}

先贴代码:

<?php
require_once('redis.php');
$redis = new  Redis();
$redis->connect();
$uid=111;
$fried_uid_list =  array(123,456,789,101);
//增加好友
foreach ($fried_uid_list as $v)
{
$redis->sadd($uid.':friend:list' ,$v);
}
//uid:sort:123
//uid对应的积分
$redis->set('uid:sort:111',9000);
$redis->set('uid:sort:123',1000);
$redis->set('uid:sort:456',6000);
$redis->set('uid:sort:789',100);
$redis->set('uid:sort:101',5999);
//uid infor
$use_infor_list =  array(
111=>array('uid'=>111,'name'=>'wgr'),
123=>array('uid'=>123,'name'=>'lucy'),
456=>array('uid'=>456,'name'=>'marry'),
789=>array('uid'=>789,'name'=>'ice'),
101=>array('uid'=>101,'name'=>'jack'),
);
foreach ($use_infor_list as $v)
{
$redis->set('uid:'.$v['uid'] ,  json_encode($v));
}
$result =  $redis->sort('111:friend:list by uid:sort:* get uid:* '  );
var_dump($result);
?>
结果是:
array(4) {
[0]=>
string(24) “{“uid”:789,”name”:”ice”}”
[1]=>
string(25) “{“uid”:123,”name”:”lucy”}”
[2]=>
string(25) “{“uid”:101,”name”:”jack”}”
[3]=>
string(26) “{“uid”:456,”name”:”marry”}”

连接控制

QUIT 关闭连接

AUTH (仅限启用时)简单的密码验证

适合全体类型的命令

EXISTS key 判断一个键是否存在;存在返回 1;否则返回0;

DEL key 删除某个key,或是一系列key;DEL key1 key2 key3 key4

TYPE key 返回某个key元素的数据类型 ( none:不存在,string:字符,list,set,zset,hash)

KEYS pattern 返回匹配的key列表 (KEYS foo*:查找foo开头的keys)

RANDOMKEY 随机获得一个已经存在的key,如果当前数据库为空,则返回空字符串

RENAME oldname newname更改key的名字,新键如果存在将被覆盖

RENAMENX oldname newname 更改key的名字,如果名字存在则更改失败

DBSIZE返回当前数据库的key的总数

EXPIRE设置某个key的过期时间(秒),(EXPIRE bruce 1000:设置bruce这个key1000秒后系统自动删除)注意:如果在还没有过期的时候,对值进行了改变,那么那个值会被清除。

TTL查找某个key还有多长时间过期,返回时间秒

SELECT index 选择数据库

MOVE key dbindex 将指定键从当前数据库移到目标数据库 dbindex。成功返回 1;否则返回0(源数据库不存在key或目标数据库已存在同名key);

FLUSHDB 清空当前数据库中的所有键

FLUSHALL 清空所有数据库中的所有键

处理字符串的命令

SET key value 给一个键设置字符串值。SET keyname datalength data (SET bruce 10 paitoubing:保存key为burce,字符串长度为10的一个字符串paitoubing到数据库),data最大不可超过1G。

GET key获取某个key 的value值。如key不存在,则返回字符串“nil”;如key的值不为字符串类型,则返回一个错误。

GETSET key value可以理解成获得的key的值然后SET这个值,更加方便的操作 (SET bruce 10 paitoubing,这个时候需要修改bruce变成1234567890并获取这个以前的数据paitoubing,GETSET bruce 10 1234567890)

MGET key1 key2 … keyN 一次性返回多个键的值

SETNX key value SETNX与SET的区别是SET可以创建与更新key的value,而SETNX是如果key不存在,则创建key与value数据

MSET key1 value1 key2 value2 … keyN valueN 在一次原子操作下一次性设置多个键和值

MSETNX key1 value1 key2 value2 … keyN valueN 在一次原子操作下一次性设置多个键和值(目标键不存在情况下,如果有一个以上的key已存在,则失败)

INCR key 自增键值

INCRBY key integer 令键值自增指定数值

DECR key 自减键值

DECRBY key integer 令键值自减指定数值

处理 lists 的命令

RPUSH key value 从 List 尾部添加一个元素(如序列不存在,则先创建,如已存在同名Key而非序列,则返回错误)

LPUSH key value 从 List 头部添加一个元素

LLEN key 返回一个 List 的长度

LRANGE key start end从自定的范围内返回序列的元素 (LRANGE testlist 0 2;返回序列testlist前0 1 2元素)

LTRIM key start end修剪某个范围之外的数据 (LTRIM testlist 0 2;保留0 1 2元素,其余的删除)

LINDEX key index返回某个位置的序列值(LINDEX testlist 0;返回序列testlist位置为0的元素)

LSET key index value更新某个位置元素的值

LREM key count value 从 List 的头部(count正数)或尾部(count负数)删除一定数量(count)匹配value的元素,返回删除的元素数量。

LPOP key 弹出 List 的第一个元素

RPOP key 弹出 List 的最后一个元素

RPOPLPUSH srckey dstkey 弹出 _srckey_ 中最后一个元素并将其压入 _dstkey_头部,key不存在或序列为空则返回“nil”

处理集合(sets)的命令(有索引无序序列)

SADD key member增加元素到SETS序列,如果元素(membe)不存在则添加成功 1,否则失败 0;(SADD testlist 3 \n one)

SREM key member 删除SETS序列的某个元素,如果元素不存在则失败0,否则成功 1(SREM testlist 3 \N one)

SPOP key 从集合中随机弹出一个成员

SMOVE srckey dstkey member 把一个SETS序列的某个元素 移动到 另外一个SETS序列 (SMOVE testlist test 3\n two;从序列testlist移动元素two到 test中,testlist中将不存在two元素)

SCARD key 统计某个SETS的序列的元素数量

SISMEMBER key member 获知指定成员是否存在于集合中

SINTER key1 key2 … keyN 返回 key1, key2, …, keyN 中的交集

SINTERSTORE dstkey key1 key2 … keyN 将 key1, key2, …, keyN 中的交集存入 dstkey

SUNION key1 key2 … keyN 返回 key1, key2, …, keyN 的并集

SUNIONSTORE dstkey key1 key2 … keyN 将 key1, key2, …, keyN 的并集存入 dstkey

SDIFF key1 key2 … keyN 依据 key2, …, keyN 求 key1 的差集。官方例子:

key1 = x,a,b,c

key2 = c

key3 = a,d

SDIFF key1,key2,key3 => x,b

SDIFFSTORE dstkey key1 key2 … keyN 依据 key2, …, keyN 求 key1 的差集并存入 dstkey

SMEMBERS key 返回某个序列的所有元素

SRANDMEMBER key 随机返回某个序列的元素

处理有序集合(sorted sets)的命令 (zsets)

ZADD key score member 添加指定成员到有序集合中,如果目标存在则更新score(分值,排序用)

ZREM key member 从有序集合删除指定成员

ZINCRBY key increment member 如果成员存在则将其增加_increment_,否则将设置一个score为_increment_的成员

ZRANGE key start end 返回升序排序后的指定范围的成员

ZREVRANGE key start end 返回降序排序后的指定范围的成员

ZRANGEBYSCORE key min max 返回所有符合score >= min和score <= max的成员 ZCARD key 返回有序集合的元素数量 ZSCORE key element 返回指定成员的SCORE值 ZREMRANGEBYSCORE key min max 删除符合 score >= min 和 score <= max 条件的所有成员

排序(List, Set, Sorted Set)

SORT key BY pattern LIMIT start end GET pattern ASC|DESC ALPHA 按照指定模式排序集合或List

SORT mylist

默认升序 ASC

SORT mylist DESC

SORT mylist LIMIT 0 10

从序号0开始,取10条

SORT mylist LIMIT 0 10 ALPHA DESC

按首字符排序

SORT mylist BY weight_*

SORT mylist BY weight_* GET object_*

SORT mylist BY weight_* GET object_* GET #

SORT mylist BY weight_* STORE resultkey

将返回的结果存放于resultkey序列(List)

持久控制

SAVE 同步保存数据到磁盘

BGSAVE 异步保存数据到磁盘

LASTSAVE 返回上次成功保存到磁盘的Unix时间戳

SHUTDOWN 同步保存到服务器并关闭 Redis 服务器(SAVE+QUIT)

BGREWRITEAOF 当日志文件过长时重写日志文件

远程控制命令

INFO 提供服务器的信息和统计信息

MONITOR 实时输出所有收到的请求

SLAVEOF 修改复制选项

redis目前提供四种数据类型:string,list,set及zset(sorted set)。

* string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操 作类似。但它的功能更丰富。

* list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。

* set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。

* zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的 值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。

协议

redis目前只有基于TCP的文本协议,与memcache类似,有一些改进。

客户端通常发送

命令 参数… 值字节数\r\n

值\r\n

服务端的返回,根据第一个字节,可以判断:

- 错误信息

+ 普通文本信息

$ 变长字节数,$6表示CRLF之后有6个字节的字符

: 返回一个整数

* 返回组数,即*6表示CRLF之后将返回6组变长字符

注意事项:

Key不可包含空格或者回车符

Key不要过长或过短,应使其有意义,如”comment:1234:reply.to”

因为十一在南昌买了房子,所以在常州的收入已无法满足资金上的要求了,另最关键的是目前常州公司在我从事的网站方面没有一个好的前景,所以打算离开。

新找的东家是上海我友网 www.woyo.com 研发部开发工程师,下周去上海了,先准备找好房子。然后25号去办理入职手续了!希望在新的公司先是能学到更多,同时希望公司能发展壮大!

购买的是buyvm.net 的15美金1年的计划,经过测试速度还是不错的。

目前先把blog搬到新的vps中,现在vps安装的是lnmp环境,这样可以更省内存!

1.认识及了解MongoDB

MongoDB 是一个面向集合的,模式自由的文档型数据库.

面向集合, 意思是数据被分组到若干集合,这些集合称作聚集(collections). 在数据库里每个聚集有一个唯一的名字,可以包含无限个文档. 聚集是RDBMS中表的同义词,区别是聚集不需要进行模式定义.
模式自由, 意思是数据库并不需要知道你将存入到聚集中的文档的任何结构信息.实际上,你可以在同一个聚集中存储不同结构的文档.
文档型, 意思是我们存储的数据是键-值对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档. 我们把这个数据格式称作 "[BSON]" 即 "Binary Serialized dOcument Notation."


集 文档数据库,键值对存储和关系型数据库的优点于一身.

MongoDB (名称来自"humongous") 是一个可扩展的,高性能,开源,模式自由,面向文档的数据库.使用C++编写,MongoDB特点:

    *     面向文档存储(类JSON数据模式简单而强大)

    *      动态查询

    *      全索引支持,扩展到内部对象和内嵌数组

    *      查询记录分析

    *      快速,就地更新

    *      高效存储二进制大对象 (比如照片和视频)

    *      复制和故障切换支持

    *     Auto- Sharding自动分片支持云级扩展性

    *      MapReduce 支持复杂聚合

    *      商业支持,培训和咨询

所 谓"面向集合"(Collenction-Orented),意思是数据被分组存储在数据集中, 被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库 (RDBMS)里的表(table),不同的是它不需要定义任何 模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同 结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于唯一标 识一个文档,为字符串类型,而值则可以是各种复杂的文件类型。我们称这种存储形式为 BSON(Binary Serialized dOcument Format)。

哪些公司在用MongoDB
sourceforge、github等。

MongoDB 有个缺点,存储的数据占用空间过大。

MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统 (丰富的功能)架起一座桥梁,集两者的优势于一身。根据官方网站的描述,Mongo 适合用于以下场景:

    * 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
    * 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
    * 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
    * 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
    * 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。

自然,MongoDB的使用也会有 一些限制,例如它不适合:

    * 高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
    * 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
    * 需要SQL的问题
Via:http://www.infoq.com/cn/news/2009/09/mongodb

性能

在 我的使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能实在让我惊讶。写入性能同样很令人满意,同样写入百万级别的数 据,mongodb比我以前试用过的couchdb要快得多,基本10分钟以下可以解决。补上一句,观察过程中mongodb都远算不上是CPU杀手。
Via:http://www.wentrue.net/blog/?p=772

2. 安装及配置
说明,MongoDB下载然后解压缩以后就可以直接使用了,不需要编译及安装。

在页面http://www.mongodb.org/display/DOCS/Downloads中找到适合于你所在操作系统的MongoDB版本。

[root@CentOS_Test_Server software]# wget http://downloads.mongodb.org/linux/mongodb-linux-i686-1.4.2.tgz

/home/software是存放软件的目录,把mongodb解压到其它的目录下

直接解压缩到目录/usr/local/webserver 下。
[root@CentOS_Test_Server software]# tar zxvf mongodb-linux-i686-1.4.2.tgz -C /usr/local/webserver/

[root@CentOS_Test_Server webserver]# ls
eaccelerator_cache  mongodb-linux-i686-1.4.2  mysql  nginx  php  squid

将目录改名,方便以后使用方便。
[root@CentOS_Test_Server webserver]# mv mongodb-linux-i686-1.4.2/ mongodb

[root@CentOS_Test_Server software]# cd /usr/local/webserver/mongodb
[root@CentOS_Test_Server mongodb]# ls
bin  GNU-AGPL-3.0  include  lib  README  THIRD-PARTY-NOTICES

直接查看README文件的内容,里面的说明对使用MongoDB也会很有帮助。
[root@CentOS_Test_Server mongodb]# more README

MongoDB
=======

Welcome to MongoDB!

Package Contents
—————-

  bin/mongod            – MongoDB server
  bin/mongo             – MongoDB client

  bin/mongodump         – MongoDB dump tool – for backups, snapshots, etc..
  bin/mongorestore      – MongoDB restore a dump
  bin/mongoexport       – Export a single collection to test (json,csv)
  bin/mongoimportjson   – Import a json file into a collection

  bin/mongofiles        – Utility for putting and getting files from MongoDB gridfs

Useful Resources
—————-

 MongoDB Website

 * http://www.mongodb.org/

Documentation

 * http://www.mongodb.org/display/DOCS/Documentation

 MongoDB Maillists & IRC

 * http://www.mongodb.org/display/DOCS/Community

如果直接输入命令./mongod,则 MongoDB的数据直接保存在/data/db目录(windows操作系统下是c:\data\db目录), 默认监听在27017端口。
如 果你启动MongoDB时没有指定任何参数,同时目录/data/db也不存在,则会报错。

[root@CentOS_Test_Server bin]# ./mongod –help | grep fork
  –fork                    fork server process
[root@CentOS_Test_Server bin]# ./mongod –help | grep dbpath
  –dbpath arg (=/data/db/) directory for datafiles
                            dbpath
  –fastsync            indicate that this instance is starting from a dbpath
[root@CentOS_Test_Server bin]# ./mongod –help | grep port
  –port arg                specify port number
  –source arg          when slave: specify master as <server:port>

运 行./mongod –help命令时mongodb提示了一下,也就是32位操作系统只支持最大2G的文件,如果你的应用中数据量很大,超过了2G,推荐安装64位的操作 系统。2Gb or Not 2Gb – File limits说明 了为什么32位操作系统只支持最大2G的文件。

[root@CentOS_Test_Server bin]# ./mongod –help | more

** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
**       see http://blog.mongodb.org/post/137788967/32-bit-limitations for more

创建目录保存MongoDB数据的目录。
[root@CentOS_Test_Server bin]# mkdir /home/mongodb_data

启动MongoDB

[root@CentOS_Test_Server bin]# ./mongod –fork –dbpath=/home/mongodb_data –logpath /home/mongodb_data/mongodb.log –logappend
all output going to: /home/mongodb_data/mongodb.log
forked process: 3799

[root@CentOS_Test_Server bin]# ps aux | grep mongo
root      3799  0.0  0.7  59032  2008 ?        Ssl  16:59   0:00 ./mongod –fork –dbpath=/home/mongodb_data –logpath /home/mongodb_data/mongodb.log –logappend
root      3825  0.0  0.2   3920   628 pts/1    S+   17:00   0:00 grep mongo

[root@CentOS_Test_Server bin]# netstat -antl | grep 27017
tcp        0      0 0.0.0.0:27017               0.0.0.0:*                   LISTEN

停止 MongoDB的进程时不能用kill -9,而最好用kill -15,否则会导致出现问题。

Sending a Unix INT or TERM signal

You can cleanly stop mongod using a SIGINT or SIGTERM signal on Unix-like systems. Either ^C, "kill -2 PID," or kill -15 PID will work.

Please note that sending a KILL signal kill -9 will probably cause damage as mongod will not be able to cleanly exit.  (In such a scenario, run the repairDatabase command.)


同时会自动启动一个端口为28017的服务,此服务用于监控MongoDB的状态
[root@CentOS_Test_Server bin]# netstat -a | grep 28017
tcp        0      0 *:28017                     *:*                         LISTEN

用curl可以在启动MongoDB所在的服务器上面直接访问, 如果想从其它的访问访问此服务,则必须在防火墙上开放28017端口。
[root@CentOS_Test_Server bin]# curl localhost:28017
<html><head><title>mongodb CentOS_Test_Server:27017 </title></head><body><h2>mongodb CentOS_Test_Server:27017 </h2><p>
<pre>db version v1.4.2, pdfile version 4.5
git hash: 53749fc2d547a3139fcf169d84d58442778ea4b0
sys info: Linux domU-12-31-39-01-70-B4 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_37
…..

我在服务器上打开了28017端口,不知道为什么 在其它的电脑上面输入地址http://192.168.1.111:28017/无法访问,暂时不知道是什么原因。
[root@CentOS_Test_Server bin]# iptables -A RH-Firewall-1-INPUT -p tcp -m state –state NEW -m tcp –dport 28017 -j ACCEPT
[root@CentOS_Test_Server bin]# /etc/init.d/iptables save
Saving firewall rules to /etc/sysconfig/iptables:          [  OK  ]

更多MongoDB启动的问题,请移步 Starting and Stopping Mongo,http://www.mongodb.org/display/DOCS/Starting+and+Stopping+Mongo

3. 测试
[root@CentOS_Test_Server bin]# ls
运行MongoDB下面bin目录下的mongo命 令,就可以进入MongoDB的shell界面了,跟MySQL有点类似,输入命令help,其它的看帮助基本上就明白了。
mongo  mongod  mongodump  mongoexport  mongofiles  mongoimport  mongorestore  mongos  mongosniff  mongostat
[root@CentOS_Test_Server bin]# ./mongo
MongoDB shell version: 1.4.2
url: test
connecting to: test
type "help" for help
> help
HELP
        show dbs                     show database names
        show collections             show collections in current database
        show users                   show users in current database
        show profile                 show most recent system.profile entries with time >= 1ms
        use <db name>                set curent database to <db name>
        db.help()                    help on DB methods
        db.foo.help()                help on collection methods
        db.foo.find()                list objects in collection foo
        db.foo.find( { a : 1 } )     list objects in foo where a == 1
        it                           result of the last line evaluated; use to further iterate

在MongoDB中,在使用Database或Collection前不需要提前创建,在使用的过程中会 自动创建。
更多的有关信息请移步MongoDB Tutorial

a.测试一
我们来测试一下就明白了
> use recommender //
在此之前我可从来没有创建过数据库recommender
> a={name: "caihuafeng"} //也就是json对象,大家看起来是不是非常熟悉
{ "name" : "caihuafeng" }
> b={website: "1616.net"}
{ "website" : "1616.net" }
> db.data.save(a) //
在此之前我可没有创建过表data,在数据库recommender的表data中保存数据a,可以理解为往MySQL的表data中添加一条记录
> db.data.save(b) //在数据库recommender的表data中保存数据b,可以理解为往MySQL的表data中添加一条记录
> db.data.find()   //显示数据库recommender的表data中的所有数据
{ "_id" : ObjectId("4bee745a0863b1c233b8b7ea"), "name" : "caihuafeng" }
{ "_id" : ObjectId("4bee745f0863b1c233b8b7eb"), "website" : "1616.net" }
> show collections //显示数据库recommender中的所有表(collection在这里相当于MySQL中的表)
data
system.indexes //这个表是自动创建的

显示数据库recommender中website为1616.net的记录,相当于MySQL中的 SELECT * FROM data WHERE website='1616.net';
> db.data.find({website:"1616.net"})
{ "_id" : ObjectId("4bee745f0863b1c233b8b7eb"), "website" : "1616.net" }

显示 数据库recommender中name为caihuafeng的记录,相当于MySQL中的SELECT * FROM data WHEREname ='caihuafeng';
> db.data.find({name:"caihuafeng"})
{ "_id" : ObjectId("4bee745a0863b1c233b8b7ea"), "name" : "caihuafeng" }

MongoDB 比其它的关系型数据库更加灵活,因为每一行的记录都可以有不同的结构,而且表的结构根本上不需要提前创建,灵活极了。

b.测试二
发现就是在写js代码,然后跟数据库结合起来了。
> for (var i = 1; i <= 10; i++) db.data.save({"x":6, "name":"caihuafeng" + i});
> db.data.find();
{ "_id" : ObjectId("4bee745a0863b1c233b8b7ea"), "name" : "caihuafeng" }
{ "_id" : ObjectId("4bee745f0863b1c233b8b7eb"), "website" : "1616.net" }
{ "_id" : ObjectId("4bee804ba23d558eb6687117"), "x" : 6, "name" : "caihuafeng1" }
{ "_id" : ObjectId("4bee804ba23d558eb6687118"), "x" : 6, "name" : "caihuafeng2" }
{ "_id" : ObjectId("4bee804ba23d558eb6687119"), "x" : 6, "name" : "caihuafeng3" }
{ "_id" : ObjectId("4bee804ba23d558eb668711a"), "x" : 6, "name" : "caihuafeng4" }
{ "_id" : ObjectId("4bee804ba23d558eb668711b"), "x" : 6, "name" : "caihuafeng5" }
{ "_id" : ObjectId("4bee804ba23d558eb668711c"), "x" : 6, "name" : "caihuafeng6" }
{ "_id" : ObjectId("4bee804ba23d558eb668711d"), "x" : 6, "name" : "caihuafeng7" }
{ "_id" : ObjectId("4bee804ba23d558eb668711e"), "x" : 6, "name" : "caihuafeng8" }
{ "_id" : ObjectId("4bee804ba23d558eb668711f"), "x" : 6, "name" : "caihuafeng9" }
{ "_id" : ObjectId("4bee804ba23d558eb6687120"), "x" : 6, "name" : "caihuafeng10" }

> var cursor = db.data.find();
> while (cursor.hasNext()) {print(tojson(cursor.next()))};
{ "_id" : ObjectId("4bee745a0863b1c233b8b7ea"), "name" : "caihuafeng" }
{ "_id" : ObjectId("4bee745f0863b1c233b8b7eb"), "website" : "1616.net" }
{
        "_id" : ObjectId("4bee804ba23d558eb6687117"),
        "x" : 6,
        "name" : "caihuafeng1"
}
{
        "_id" : ObjectId("4bee804ba23d558eb6687118"),
        "x" : 6,
        "name" : "caihuafeng2"
}
{
        "_id" : ObjectId("4bee804ba23d558eb6687119"),
        "x" : 6,
        "name" : "caihuafeng3"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711a"),
        "x" : 6,
        "name" : "caihuafeng4"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711b"),
        "x" : 6,
        "name" : "caihuafeng5"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711c"),
        "x" : 6,
        "name" : "caihuafeng6"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711d"),
        "x" : 6,
        "name" : "caihuafeng7"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711e"),
        "x" : 6,
        "name" : "caihuafeng8"
}
{
        "_id" : ObjectId("4bee804ba23d558eb668711f"),
        "x" : 6,
        "name" : "caihuafeng9"
}
{
        "_id" : ObjectId("4bee804ba23d558eb6687120"),
        "x" : 6,
        "name" : "caihuafeng10"
}

> db.data.find({x:6}, {name:true}).forEach(function(x) {print(tojson(x));});
{ "_id" : ObjectId("4bee804ba23d558eb6687117"), "name" : "caihuafeng1" }
{ "_id" : ObjectId("4bee804ba23d558eb6687118"), "name" : "caihuafeng2" }
{ "_id" : ObjectId("4bee804ba23d558eb6687119"), "name" : "caihuafeng3" }
{ "_id" : ObjectId("4bee804ba23d558eb668711a"), "name" : "caihuafeng4" }
{ "_id" : ObjectId("4bee804ba23d558eb668711b"), "name" : "caihuafeng5" }
{ "_id" : ObjectId("4bee804ba23d558eb668711c"), "name" : "caihuafeng6" }
{ "_id" : ObjectId("4bee804ba23d558eb668711d"), "name" : "caihuafeng7" }
{ "_id" : ObjectId("4bee804ba23d558eb668711e"), "name" : "caihuafeng8" }
{ "_id" : ObjectId("4bee804ba23d558eb668711f"), "name" : "caihuafeng9" }
{ "_id" : ObjectId("4bee804ba23d558eb6687120"), "name" : "caihuafeng10" }

只取前3条记录,跟MySQL中的limit是类似的意思。
> db.data.find().limit(3);
{ "_id" : ObjectId("4bee745a0863b1c233b8b7ea"), "name" : "caihuafeng" }
{ "_id" : ObjectId("4bee745f0863b1c233b8b7eb"), "website" : "1616.net" }
{ "_id" : ObjectId("4bee804ba23d558eb6687117"), "x" : 6, "name" : "caihuafeng1"

4.MongoDB的主从复制(Master/Slave)配置及测试

主从复制有什么用呢? 比如,在两台服务器上分别部署了MongoDB,当一台出现了问题以后,另外一台可以接管服务,同时也起备份的作用。
MongoDB supports replication of data between servers for failover and redundancy.

MongoDB支持4种形式的复制,推荐用master/slave复制
    *  Master-Slave Replication
    * Replica Pairs
    * Replica Sets
    * Limited Master-Master Replication

All else being equal, master/slave is recommended for MongoDB version 1.4.

与Master及Slave相关的帮助选项
[root@CentOS_Test_Server bin]# ./mongod –help | grep master
  –master              master mode
  –source arg          when slave: specify master as <server:port>
                        master ops to slave

[root@CentOS_Test_Server bin]# ./mongod –help | grep slave
  –slave               slave mode
  –source arg          when slave: specify master as <server:port>
  –only arg            when slave: specify a single database to replicate
  –slavedelay arg      specify delay (in seconds) to be used when applying
                        master ops to slave
  –autoresync          automatically resync if slave data is stale

启动MongoDB的Master服务
[root@CentOS_Test_Server bin]# ./mongod –fork –master –dbpath /home/masterdb/ –port 27018 –logpath /home/masterdb/mongodb.log –logappend
all output going to: /home/masterdb/mongodb.log
forked process: 11463
[root@CentOS_Test_Server bin]# ls /home/masterdb/
local.0  local.ns  mongodb.log  mongod.lock

启动MongoDB的Slave服务
[root@CentOS_Test_Server bin]# ./mongod –fork –slave –source localhost:27018 –autoresync –slavedelay 30 –dbpath /home/slavedb/ –port 27019 –logpath /home/slavedb/mongodb.log –logappend
all output going to: /home/slavedb/mongodb.log
forked process: 11848
[root@CentOS_Test_Server bin]# ls /home/slavedb/
local.0  local.ns  mongodb.log  mongod.lock  _tmp

测试主从复制的功能
登录到 MongoDB的Master服务,插入一条数据
[root@CentOS_Test_Server bin]# ./mongo localhost:27018
MongoDB shell version: 1.4.2
url: localhost:27018
connecting to: localhost:27018/test
type "help" for help
> use recommender
switched to db recommender
> db.data.insert({name: "caihuafeng"})
> db.data.find()
{ "_id" : ObjectId("4beedc31e0e4fff2ce0295f6"), "name" : "caihuafeng" }

登录MongoDB的Slave服务,我们发现刚才保存到Master里面的数据已经复制到Slave了,这正是我们要看到的效果。
[root@CentOS_Test_Server bin]# ./mongo localhost:27019
MongoDB shell version: 1.4.2
url: localhost:27019
connecting to: localhost:27019/test
type "help" for help
> use recommender
switched to db recommender
> db.data.find()
{ "_id" : ObjectId("4beedc31e0e4fff2ce0295f6"), "name" : "caihuafeng" }

我们再看一下Slave服务上面产生的同步日志(/home/slavedb/mongodb.log)
Sun May 16 01:39:29 repl: from host:localhost:27018
Sun May 16 01:39:29 resync: dropping database recommender
Sun May 16 01:39:29 resync: cloning database recommender to get an initial copy
Sun May 16 01:39:29 allocating new datafile /home/slavedb/recommender.ns, filling with zeroes…
Sun May 16 01:39:29 done allocating datafile /home/slavedb/recommender.ns, size: 16MB, took 0.451 secs
Sun May 16 01:39:29 allocating new datafile /home/slavedb/recommender.0, filling with zeroes…
Sun May 16 01:39:31 done allocating datafile /home/slavedb/recommender.0, size: 64MB, took 1.397 secs
Sun May 16 01:39:31 allocating new datafile /home/slavedb/recommender.1, filling with zeroes…
Sun May 16 01:39:31 building new index on { _id: 1 } for recommender.data
Sun May 16 01:39:31 Buildindex recommender.data idxNo:0 { name: "_id_", ns: "recommender.data", key: { _id: 1 } }

为 了让MongoDB的主从服务可以自动启动,可以把下面的两条命令加到/etc/rc.local中。
/usr/local/webserver/mongodb/bin/mongod –fork –master –dbpath /home/masterdb/ –port 27018 –logpath /home/masterdb/mongodb.log –logappend

/usr/local/webserver/mongodb/bin/mongod –fork –slave –source localhost:27018 –autoresync –slavedelay 30 –dbpath /home/slavedb/ –port 27019 –logpath /home/slavedb/mongodb.log –logappend

附:
Sun May 16 00:59:47 waiting for connections on port 27018
Sun May 16 00:59:47 web admin interface listening on port 28018

Sun May 16 01:12:27 waiting for connections on port 27019
Sun May 16 01:12:27 web admin interface listening on port 28019

mongodb的端口为27017时,相应的web admin监听的端口为28017
mongodb 的端口为27018时,相应的web admin监听的端口为28018
mongodb的端口为27019时,相应的web admin监听的端口为28019

找到了一个规律,就是web admin的端口就是将mongodb的端口的第二位改为8,猜测应该是这样的。

http://www.mongodb.org/display/DOCS/Master+Slave
http://www.mongodb.org/display/DOCS/Replication

5.MongoDB的Sharding功能
MongoDB的Sharding功能将在1.6版本中出现,将在2010年7月份发布。

MongoDB has been designed to scale horizontally via an auto-sharding architecture. Auto-sharding permits the development of large-scale data clusters that incorporate additional machines dynamically, automatically accomodate changes in load and data distribution, and ensure automated failover.

Sharding will be production-ready in MongoDB v1.6, estimated to be released in July, 2010. In the meantime, an alpha version of sharding is available in the 1.5.x development branch. Please see the limitations page for progress updates and current restrictions.

http://www.mongodb.org/display/DOCS/Sharding

6. 总结
在 写这篇文章以前,我没有用过MongoDB, 以前简单的看过一些MongoDB的资料,只是有点了解,今天自己动手安装测试了一下以后对MongoDB有了更加深入一点的了解,再学习几天基本上就可 以在项目中实际使用了,比如MongoDB的读写性能也有必要再测试一下,虽然已经有不少人已经测试过了,证明MongoDB的读写性能比MySQL高, 不过功能没有MySQL强。

其实TC的Table Database也能实现一些关系型数据库的功能,也是值得深入研究一下的,其实以前我简单的研究过。Tokyo Cabinet及Tokyo Tyrant的命令行接口

Table Database的特点是支持检索,支持多列字段,支持列索引,性能不如其它结构。
Table Database提供了类似RMDB的存储功能,一个主键可以有多个字段,例如,在RMDB中user表可能会有user_id、name和 password等字段,而在Table Database也提供这种支持。
Via:http://willko.javaeye.com/blog/506728

http://zhliji2.blogspot.com/2009/05/tokyo-cabinetdbm.html

下面的文章也比较精彩,对MongoDB感兴趣的可以看一看。
[译] MongoDB 入门教程:http://chenxiaoyu.org/blog/archives/242
http://www.fuchaoqun.com/2010/01/mongodb-in-action/
http://blog.chenlb.com/2010/05/mongodb-vs-mysql-query-performance.html
http://www.wentrue.net/blog/?p=772
http://www.mikespook.com/index.php/archives/524
http://hi.baidu.com/ywdblog/blog/item/44e02e9bfe5a87bfc8eaf425.html
http://www.infoq.com/cn/news/2009/09/mongodb
MongoDB 1.6 发布:
http://xiexiejiao.cn/database/mongodb-1-6-release.html
http://m.cnblogs.com/66952/1673308.html

MongoDB中文介绍:http://www.mongodb.org/display/DOCSCN/Home
MongoDB文档首 页:
http://www.mongodb.org/display/DOCS/Home

考虑再三还是决定回南昌买房,常州房价涨得太猛了。偏到高铁站那边去了,去年3400一平没买现在5200以上了,靠!

郁闷的是南昌最近开始城市改造,大量拆迁户拿政府8000一平方的补贴进入楼市买房,南昌房价又火起来了,看起来国家11条打压房价再次失败了,以后不相信政府了。还是早买早好,省得又白打工几年。

本来是想去北京东路附近买的,方便以后亲戚窜门,但是他妈的不是一般的贵,一个楼盘花了1万块预定,号不太好,一个小时后就剩1楼了,妈的!最后看了青云谱包家花园附近的房子,可是房子都只有一楼和顶楼,我的天啊,而且还一天一个价。后来没办法,只能订了城东一套房子。94平方44万,首付得3成,靠,已付了5万块的定金!这次中秋回南昌去交首付和办理贷款。

接下来的几年就要天天想着还贷了。最近几年不再关注楼市的事,太他妈的不是人干的事了。他妈的共产党你真心想把房价降下来就放剂猛药不就得了,听说欧洲不允许有空房,空房一定年限后国家收回分给没房的人住。现在国家只是控制控制银行贷款,但是炒房投机的人人,人家直接全额买可以么。靠!