主动发送信息实现过程:
机器人通过http去指定的url上去获取单条要给机器人发送的信息,为空的话,隔5秒后再取,不为空,取出并且机器人发送本条信息,同时下次取信息时,会把这条已发送的信息的ID通过POST传给http,通知web程序本条信息已成功发出!
程序写好,编译也通过了,但是公司上网要走公司的代理,所以qq机器人暂时还没有通过测试,先在博客里记录一下,回家后再测
目前机器人处开发阶段,设定了一个时间,机器人登陆后60秒左右后会自动下线!
主动发送信息实现过程:
机器人通过http去指定的url上去获取单条要给机器人发送的信息,为空的话,隔5秒后再取,不为空,取出并且机器人发送本条信息,同时下次取信息时,会把这条已发送的信息的ID通过POST传给http,通知web程序本条信息已成功发出!
程序写好,编译也通过了,但是公司上网要走公司的代理,所以qq机器人暂时还没有通过测试,先在博客里记录一下,回家后再测
目前机器人处开发阶段,设定了一个时间,机器人登陆后60秒左右后会自动下线!
需求:多台memcache共同工作,一台memcache服务器为主服务器A 其它的memcache服务器为B,C,D…
后台对memcache进行delete及set操作时,把操作命令存至redis或是其它媒介中,采用redis lists 做一简单的队阵方式保存操作的命令,也就是把A的日志记录压入队阵中
然后服务器跑一php的脚本,不停的循环从redis 中弹出A的命令日志,最后,把命令给B,C,D等从服务器执行,这样就达到了主从一至的要求。
目前只是简单的想法,准备找时间深入一下,弄一个主从备份的脚本,并且加上主从切换的功能。
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节点信息:
[codesyntax lang=”php”]
<?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' ), );
[/codesyntax]
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之类的反向代理服务,基本上就不会有问题。
[codesyntax lang="php"]
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); } }[/codesyntax]
先贴代码:
//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);
?>
连接控制
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环境,这样可以更省内存!