游戏服务器使用MongoDB作为缓存数据库有哪些,还有必要使用Redis缓存吗

OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;
欢迎您订阅我们的技术周刊
我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,
欢迎分享您的观点,经验,技巧,心得
让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;
本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(
订阅邮件周刊
在nodejs中使用Redis缓存和查询数据及Session持久化(Express)
注意 转载须保留原文链接,译文链接,作者译者等信息。&&
在之前的这篇文章 在ExpressJS(NodeJS)中 中提及将Session存放到Mongodb中,其中有很多讲解的不是很详细。我们为什么要把Session存放到数据中,以及又为什么要在子域名间跨域共享Cookie呢?Session与Cookie的关系客户端与服务会使用一个Sessionid的Cookie值来进行客户端和服务器端会话的匹配,这个Cookie一般是服务器端读/写的,并在Http请求响应的Header中的Set-Cookie属性设置:HTTP/1.1 200 OKServer: nginxDate: Wed, 14 Jan :09 GMTContent-Type: text/htmlTransfer-Encoding: chunkedProxy-Connection: Keep-AliveConnection: Keep-AliveContent-Encoding: gzipSet-Cookie: sessionid=i4w3axuzyj4nwwg75y6k5us2; path=/; domain=.; httponlypath=/&&&&&&&&&&&& 表示这个cookie是设置在根目录的。httponly&&&&&&&&&& 属性禁止客户端JavaScript的访问,防止当前会话(sessionid)被恶意的js脚本盗取domain=.& 表示将sessionid存放到主域名下,各个二级域名域名均使用此Cookie (sessionid)注* 中间代理人攻击,即是通过代理服务器(如无线路由)盗取你的会话Cookie(SessionID等),从而访冒你的身份。因此Google建议网站全部采用HTTPS协议,加密传输内容,并提高了纯HTTPS网站的权重。使用数据库来集中管理session,存放Session内容,并在各个子域名跨域共享Cookies (SessionID),即可实现为每一个子域分配一个独立的node.js Web服务器,各个服务程序均可依据sessionid从数据库中寻找到同一Session,从而实现不同Web Server中的会话同步,从而实现一定程度上的负载均衡。要想实现完全意义的负载均衡还需要将Web服务做到完全状态无关,不仅仅是Session,所有的中间缓存数据都要转移到与服务器无关的缓存层中,这正是Redis最善长的地方。但是为什么存放在Redis中要比MongoDB中好呢?将Session存放到MongoDB在MongoDB中是这样存放Session的, 使用 & 即用来将Express中的Session持久化到Mongodb的一个中间件,它也可以在上使用。Express 4.x, 5.0 与 Connect 3.x配合使用:var session = require('express-session');var MongoStore = require('connect-mongo')(session);app.use(session({&&& secret: 'foo',&&& store: new MongoStore(options)}));Express 2.x, 3.x 和 Connect 1.x, 2.x配合使用:var MongoStore = require('connect-mongo')(express);app.use(express.session({&&& secret: 'foo',&&& store: new MongoStore(options)}));对于 Connect 只需要将express替换成connect即可 是一个基于文档的数据库,所有数据是从磁盘上进行读写的。MongoDB善长的是对无模式JSON数据的查询。而Redis是一个基于内存的键值数据库,它由C语言实现的,与Nginx/ NodeJS工作原理近似,同样以单线程异步的方式工作,先读写内存再异步同步到磁盘,读写速度上比MongoDB有巨大的提升。因此目前很多超高并发的网站/应用都使用Redis做缓存层,普遍认为其性能明显好于MemoryCache。当并发达到一定程度时,即可考虑使用Redis来缓存数据和持久化Session。在NodeJS中使用Redis缓存数据Redis () 数据库采用极简的设计思想,最新版的源码包还不到2Mb。其在使用上也有别于一般的数据库。node_redisredis驱动程序多使用  此模块可搭载官方的 hiredis C 语言库 - 同样是非阻塞的,比使用JavaScript内置的解释器性能稍好。可选择将hiredis 与 redis 一同安装。npm install hiredis redis如果 hiredis 安装成功, node_redis 会默认使用 hiredis, 否则会使用JavaScript的解释器。Redis的一个Key不仅可以对应一个String类型的值,还支持hashes, lists, sets, sorted sets, bitmaps等。比如存/取一组Hash值,Redis中有两个对应的 HMSET key field value [field value ...]、为一个Key一次设置多个哈希键/值, 多用于JSON对象的写入(序列化的SESSION)。HGETALL key读取一个Key的所有 哈希键/值,多用于JSON对象读取这两个命令即是在NodeJS中存取JSON对象的关键,下面是node_reids中对应的例子:var redis = require("redis"),&&& client = redis.createClient();//写入JavaScript(JSON)对象client.hmset('sessionid', { username: 'kris', password: 'password' }, function(err) {& console.log(err)})//读取JavaScript(JSON)对象client.hgetall('sessionid', function(err, object) {& console.log(object)})Redis没有严格意义上的表名和字段名,以 Key-Value 键值对的方式存储,因此一般采用 schema:key 形式做为键值,其中schema:& 可理解为传统数据库中的表名key:    可理解为表中的主键因此使用redis存放你的session时,需要一个schema前辍, 比如这个key: sessionid:i4w3axuzyj4nwwg75y6k5us2Redis 也仅能对Key进行检索, 尚不支持对Key所存放的Hash Key的检索。 如要检索到所有session,只需匹配 sessionid:* 即可, client.keys('session:*', function (err, keys) {& console.log(keys)})有些第三方库会支持检索值中的Hash Key,但这不是一个原子性操作,redis本身并不提供。 因此在采用Redis缓存与检索数据时,要使用一些独特的数据类型,如集合(Sets)& sadd myset 1 2 3&&& //添加 1 2 3到集合myset(integer) 3& smembers myset&&&&& //列出集合的所有成员1. 32. 13. 2& sismember myset 30& //判断30是否存在(integer) 0&&&&&&&&&& //不存在Redis集合不允许添加相同成员。多次添加同一元素到集合中最终只会包含一个元素。多个集合之间可以进行连接/交集这样的操作。从而实现类似传统数据库中索引、条件和连接查询的效果。# 添加 3 个用户和信息hmset user:1 user_name lee age 21hmset user:2 user_name david age 25hmset user:3 user_name chris age 25# 维护age索引sadd age:21 1sadd age:25 2 3# 维护name索引sadd name:lee 1sadd name:david 2sadd name:chris 3# 查找& age = 25 和 name = lee 的用户sinter age:25 name:lee& -& 会返回一个空集合将Session存放到Redis中  是一个 Redis 版的 session 存储器,使用node_redis作为驱动。借助它即可在Express中启用Redis来持久化你的Session.安装$ npm install connect-redis在 Express 3.x 中还需要安装express-session $ npm install express-session参数client 你可以复用现有的redis客户端对象, 由 redis.createClient() 创建host&& Redis服务器名port&& Redis服务器端口socket Redis服务器的unix_socket可选参数ttl&&&&&&& Redis session TTL 过期时间 (秒)disableTTL 禁用设置的 TTLdb&&&&&&&& 使用第几个数据库pass&&&&&& Redis数据库的密码prefix&&&& 数据表前辍即schema, 默认为 "sess:"使用将express-session传给connect-redis来启用var session = require('express-session');var RedisStore = require('connect-redis')(session);app.use(session({&&& store: new RedisStore(options),&&& secret: 'keyboard cat'}));检验app.use(function (req, res, next) {& if (!req.session) {&&& return next(new Error('oh no')) // handle error& }& next() // otherwise continue})这样你的Session就转移到了Redis数据库,这样做的一个额外好处是,当你的Express服务器突然重启后,用户仍然可以使用当前Cookie中的SessionID从数据库中获取到他的会话状态,做到会话不丢失,在一定程度上提高网站的键壮性。如果你的NodeJS网站上的所有缓存数据都转移到了Redis后,就可做到完全状态无关,按需扩展网站的规模。可水平扩展的NodeJS网站服务器集群(非 & 不同,它们是相互独立的,可分布在不同的物理服务器上),这样的架构,对于应对超大规模并发也是有好处的。
给我带来了很大帮助谢谢
alert('1');
cluster模块 也可以这样做分布在不同物理服务器上吧?反正都是用redis缓冲
请问,这个的意思是吧redis安装在另外的服务器上,我尝试过,安在和node同一台机器上,cluster模式可以共享session,但是redis安装在其他机器上就链接补上redis了,请问这是什么原因
@侯优仪 #10
一般是Reids的设置问题,你可以试试
1) 检查一下redis服务器的防火墙设置。
看看redis是否限制只允许本机访问,如:
bind 127.0.0.1 ,如果有先注释掉。
3)如果允许外网访问,请确保redis 设置了访问密码,如: requirepass password 并检查是否与 node.js 中写的一致
@蒲丹示 #6
Alert("err")
&热门文章 - 分享最多
&相关阅读 - JS学习
&关键字 - Node.JS
&欢迎订阅 - 技术周刊
我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;
我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊把 MongoDB 当成是纯内存数据库来使用(Redis 风格) - 技术翻译 - 开源中国社区
把 MongoDB 当成是纯内存数据库来使用(Redis 风格)
【已翻译100%】
英文原文:
推荐于 4年前 (共 5 段, 翻译完成于 05-04)
参与翻译&(1人)&:
将MongoDB用作内存数据库(in-memory database),也即,根本就不让MongoDB把数据保存到磁盘中的这种用法,引起了越来越多的人的兴趣。这种用法对于以下应用场合来讲,超实用:
置于慢速RDBMS系统之前的写操作密集型高速缓存
嵌入式系统
无需持久化数据的PCI兼容系统
需要轻量级数据库而且库中数据可以很容易清除掉的单元测试(unit testing)
如果这一切可以实现就真是太优雅了:我们就能够巧妙地在不涉及磁盘操作的情况下利用MongoDB的查询/检索功能。可能你也知道,在99%的情况下,磁盘IO(特别是随机IO)是系统的瓶颈,而且,如果你要写入数据的话,磁盘操作是无法避免的。
MongoDB有一个非常酷的设计决策,就是她可以使用内存影射文件(memory-mapped file)来处理对磁盘文件中数据的读写请求。这也就是说,MongoDB并不对RAM和磁盘这两者进行区别对待,只是将文件看作一个巨大的数组,然后按照字节为单位访问其中的数据,剩下的都交由操作系统(OS)去处理!就是这个设计决策,才使得MongoDB可以无需任何修改就能够运行于RAM之中。
&翻译得不错哦!
这一切都是通过使用一种叫做tmpfs的特殊类型文件系统实现的。在Linux中它看上去同常规的文件系统(FS)一样,只是它完全位于RAM中(除非其大小超过了RAM的大小,此时它还可以进行swap,这个非常有用!)。我的服务器中有32GB的RAM,下面让我们创建一个16GB的 tmpfs:
# mkdir /ramdata
# mount -t tmpfs -o size=16000M tmpfs /ramdata/
Filesystem
Used Available Use% Mounted on
/dev/xvde1
0% /dev/shm
0% /ramdata
接下来要用适当的设置启动MongoDB。为了减小浪费的RAM数量,应该把smallfiles和noprealloc设置为true。既然现在是基于RAM的,这么做完全不会降低性能。此时再使用journal就毫无意义了,所以应该把nojournal设置为true。
dbpath=/ramdata
nojournal = true
smallFiles = true
noprealloc = true
MongoDB启动之后,你会发现她运行得非常好,文件系统中的文件也正如期待的那样出现了:
MongoDB shell version: 2.3.2
connecting to: test
& db.test.insert({a:1})
& db.test.find()
{ "_id" : ObjectId("eafa5d80b5d2c145"), "a" : 1 }
# ls -l /ramdata/
total 65684
-rw-------. 1 root root
Apr 30 15:52 local.0
-rw-------. 1 root root
Apr 30 15:52 local.ns
-rwxr-xr-x. 1 root root
5 Apr 30 15:52 mongod.lock
-rw-------. 1 root root
Apr 30 15:52 test.0
-rw-------. 1 root root
Apr 30 15:52 test.ns
drwxr-xr-x. 2 root root
40 Apr 30 15:52 _tmp
现在让我们添加一些数据,证实一下其运行完全正常。我们先创建一个1KB的document,然后将它添加到MongoDB中4百万次:
& str = ""
& aaa = "aaaaaaaaaa"
aaaaaaaaaa
& for (var i = 0; i & 100; ++i) { str += }
& for (var i = 0; i & 4000000; ++i) { db.foo.insert({a: Math.random(), s: str});}
& db.foo.stats()
"ns" : "test.foo",
"count" : 4000000,
"size" : ,
"avgObjSize" : ,
"storageSize" : ,
"numExtents" : 26,
"nindexes" : 1,
"lastExtentSize" : ,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : ,
"indexSizes" : {
&翻译得不错哦!
可以看出,其中的document平均大小为1136字节,数据总共占用了5GB的空间。_id之上的索引大小为130MB。现在我们需要验证一件
非常重要的事情:RAM中的数据有没有重复,是不是在MongoDB和文件系统中各保存了一份?还记得MongoDB并不会在她自己的进程内缓存任何数据,她的数据只会缓存到文件系统的缓存之中。那我们来清除一下文件系统的缓存,然后看看RAM中还有有什么数据:
# echo 3 & /proc/sys/vm/drop_caches
-/+ buffers/cache:
可以看到,在已使用的6.3GB的RAM中,有5.8GB用于了文件系统的缓存(缓冲区,buffer)。为什么即使在清除所有缓存之后,系统中仍然还有5.8GB的文件系统缓存??其原因是,Linux非常聪明,她不会在tmpfs和缓存中保存重复的数据。太棒了!这就意味着,你在RAM只有一份数据。下面我们访问一下所有的document,并验证一下,RAM的使用情况不会发生变化:
& db.foo.find().itcount()
-/+ buffers/cache:
# ls -l /ramdata/
total 5808780
-rw-------. 1 root root
Apr 30 15:52 local.0
-rw-------. 1 root root
Apr 30 15:52 local.ns
-rwxr-xr-x. 1 root root
5 Apr 30 15:52 mongod.lock
-rw-------. 1 root root
Apr 30 16:00 test.0
-rw-------. 1 root root
Apr 30 16:00 test.1
-rw-------. 1 root root
Apr 30 16:02 test.10
-rw-------. 1 root root
Apr 30 16:03 test.11
-rw-------. 1 root root
Apr 30 16:03 test.12
-rw-------. 1 root root
Apr 30 16:04 test.13
-rw-------. 1 root root
Apr 30 16:04 test.14
-rw-------. 1 root root
Apr 30 16:00 test.2
-rw-------. 1 root root
Apr 30 16:00 test.3
-rw-------. 1 root root
Apr 30 16:00 test.4
-rw-------. 1 root root
Apr 30 16:01 test.5
-rw-------. 1 root root
Apr 30 16:01 test.6
-rw-------. 1 root root
Apr 30 16:04 test.7
-rw-------. 1 root root
Apr 30 16:03 test.8
-rw-------. 1 root root
Apr 30 16:02 test.9
-rw-------. 1 root root
Apr 30 15:52 test.ns
drwxr-xr-x. 2 root root
40 Apr 30 16:04 _tmp
Filesystem
Used Available Use% Mounted on
/dev/xvde1
0% /dev/shm
% /ramdata
果不其然! :)
&翻译得不错哦!
复制(replication)呢?
既然服务器在重启时RAM中的数据都会丢失,所以你可能会想使用复制。采用标准的副本集(replica set)就能够获得自动故障转移(failover),还能够提高数据读取能力(read capacity)。如果有服务器重启了,它就可以从同一个副本集中另外一个服务器中读取数据从而重建自己的数据(重新同步,resync)。即使在大量数据和索引的情况下,这个过程也会足够快,因为索引操作都是在RAM中进行的 :)
有一点很重要,就是写操作会写入一个特殊的叫做oplog的collection,它位于local数据库之中。缺省情况下,它的大小是总数据量的5%。在我这种情况下,oplog会占有16GB的5%,也就是800MB的空间。在拿不准的情况下,比较安全的做法是,可以使用oplogSize这个选项为oplog选择一个固定的大小。如果备选服务器宕机时间超过了oplog的容量,它就必须要进行重新同步了。要把它的大小设置为1GB,可以这样:
oplogSize = 1000
&翻译得不错哦!
分片(sharding)呢?
既然拥有了MongoDB所有的查询功能,那么用它来实现一个大型的服务要怎么弄?你可以随心所欲地使用分片来实现一个大型可扩展的内存数据库。配置服务器(保存着数据块分配情况)还还是用过采用基于磁盘的方案,因为这些服务器的活动数量不大,老从头重建集群可不好玩。
RAM属稀缺资源,而且在这种情况下你一定想让整个数据集都能放到RAM中。尽管tmpfs具有借助于磁盘交换(swapping)的能力,但其性能下降将非常显著。为了充分利用RAM,你应该考虑:
使用usePowerOf2Sizes选项对存储bucket进行规范化
定期运行compact命令或者对节点进行重新同步(resync)
schema的设计要相当规范化(以避免出现大量比较大的document)
宝贝,你现在就能够将MongoDB用作内存数据库了,而且还能使用她的所有功能!性能嘛,应该会相当惊人:我在单线程/核的情况下进行测试,可以达到每秒20K个写入的速度,而且增加多少个核就会再增加多少倍的写入速度。
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们
我又重新看了一下原文,感觉这个翻译的确会有点问题,原文的意思貌似是每秒20k次写入,而不是我翻译的可能会让人领会为每秒20kB的写入速度
原理上可以这么说,但有些数据库在设计时并未考虑使用内存作为文件系统,它们在保存数据时除了保存用户数据之外还会保存大量的衍生数据,使得这样的数据库作为内存数据库使用时内存使用效率极其低下,所以拿它们来做内存数据库就相当不合适了。
可能在查询功能和索引方面MonogoDB会略胜一筹?
嗯,这种用法只能是在适当的场合下使用。不过我感觉在集群中使用应该算是相当可靠了
和键值对还是很大区别的。我们数据库做键值对应用,单核的检索是400万行/秒。redis其实是个效率很低的东西。
redis...记不清了,不好意思
和键值对还是很大区别的。我们数据库做键值对应用,单核的检索是400万行/秒。redis其实是个效率很低的东西。啊??
和键值对还是很大区别的。我们数据库做键值对应用,单核的检索是400万行/秒。redis其实是个效率很低的东西。啊??求对比/分析报告
表现一下而已,国货当自强先说我自己用的情况:
最先用的memcache ,用于键值对关系的服务器端缓存,用于存储一些常用的不是很大,但需要快速反应的数据
然后,在另一个地方,要用到redis,然后就去研究了下redis.
一看,显示自己安装了php扩展,因为有服务器上的redis服务端,自己本地就没有安装,其实用法和memcache基本一样,可能就是几个参数有所不
同。当然 它们缓存的效果也不一样,具体的哪里不一样,一下就是一些资料,和自己的总结
1、 Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
2、 数据类型--Memcache在添加数据时就要指定数据的字节长度,例如:
& set key3 0 0 8
& lxsymcto
而redis不需要,如:redis 127.0.0.1:6379&set key2 "lxsymblog"
& redis 127.0.0.1:6379&get key2
& "lxsymblog"
3、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘
4、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10
5、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从
6、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
7、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复
从以下几个维度,对redis、memcache、mongoDB&做了对比,欢迎拍砖
都比较高,性能对我们来说应该都不是瓶颈
总体来讲,TPS方面redis和memcache差不多,要大于mongodb
2、操作的便利性
&&&&& memcache数据结构单一
&&&&& redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数
&&&&&& mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富
3、内存空间的大小和数据量的大小
&&&&&& redis在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key
value设置过期时间(类似memcache)
&&&&&& memcache可以修改最大可用内存,采用LRU算法
&&&&&& mongoDB适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起
4、可用性(单点问题)
对于单点问题,
&&&&&&&&&&&& redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,
所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash&机制。
一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡
&&&&&&&&&&&& Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。
&&&&&&&&&&&& mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto
sharding机制,对客户端屏蔽了故障转移和切分机制。
5、可靠性(持久化)
对于数据持久化和数据恢复,
&&&&&&&& redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响
&&&&&&&&& memcache不支持,通常用在做缓存,提升性能;
&&&&&&&&& MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性
6、数据一致性(事务支持)
&&&&&&&& Memcache&在并发场景下,用cas保证一致性
&&&&&&& redis事务支持比较弱,只能保证事务中的每个操作连续执行
&&&&&&& mongoDB不支持事务
7、数据分析
&&&&&&&& mongoDB内置了数据分析的功能(mapreduce),其他不支持
8、应用场景
&&&&&&& redis:数据量较小的更性能操作和运算上
&&&&&&& memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)
&&&&&&& MongoDB:主要解决海量数据的访问效率问题
最近一直在研究key-value的存储,简单记一下感受。。一些memcache和redis的安装和使用就不赘述啦。只简单说说两种方案的差别。一些
感想和测试结果未必足够能说明问题,有什么不妥请大家指正。因为这两天在学习的过程发现一直在更正自己认识的缺陷,每天都会否定前一天的想法。。好了,费
  经过对50万个数据存储的研究发现:
  每秒单条指令执行量    
&& &memcache &约3万次
  redis & & 约1万次
&& &而且,memcache的一大优点是可以通过一个函数直接设置过期时间,而redis需要两个函数才可以既设置了键值对又设置过期时间,也就是redis在这点上效率变成了原来的一半,即5千次,这对于大部分需求来说,有点太慢了。
  memcache的测试代码如下:
$mem = new M
$mem-&connect("127.0.0.1", 11211);
$time_start = microtime_float();
//保存数据
for($i = 0; $i & 100000; $i ++){
&& &$mem-&set("key$i",$i,0,3);
$time_end = microtime_float();
$run_time = $time_end - $time_
echo "用时 $run_time 秒\n";
function microtime_float()
&& &list($usec, $sec) = explode(" ", microtime());
&& &return ((float)$usec + (float)$sec);
  redis的测试代码如下:redis1.php 此代码大概需要10秒左右
$redis = new Redis();
$redis-&connect('127.0.0.1', 6379);
$time_start = microtime_float();
//保存数据
for($i = 0; $i & 100000; $i ++){
&& &$redis-&sadd("key$i",$i);
$time_end = microtime_float();
$run_time = $time_end - $time_
echo "用时 $run_time 秒\n";
//关闭连接
$redis-&close();
function microtime_float()
&& &list($usec, $sec) = explode(" ", microtime());
&& &return ((float)$usec + (float)$sec);
  如果需要在设置键值的同时设置过期时间,大概执行需要20秒左右,测试代码如下:redis2.php
$redis = new Redis();
$redis-&connect('127.0.0.1', 6379);
$time_start = microtime_float();
//保存数据
for($i = 0; $i & 100000; $i ++){
&& &$redis-&sadd("key$i",$i);
&& &$redis-&expire("key$i",3);
$time_end = microtime_float();
$run_time = $time_end - $time_
echo "用时 $run_time 秒\n";
//关闭连接
$redis-&close();
function microtime_float()
&& &list($usec, $sec) = explode(" ", microtime());
&& &return ((float)$usec + (float)$sec);
  后来在网上发现redis有一个神奇的功能叫事务,通过multi原子性的将一段代码块依次执行,从而达到一个完整功能模块的执行。不幸的是,通过测
试发现,采用multi方式执行代码时并没有减少请求次数,相反在执行multi指令和exec指令时都要发送请求,从而将运行时间变成了原来的四倍,即
四条指令的运行时间。测试代码如下:redis3.php
$redis = new Redis();
$redis-&connect('127.0.0.1', 6379);
$time_start = microtime_float();
//保存数据
for($i = 0; $i & 100000; $i ++){
&& &$redis-&multi();
&& &$redis-&sadd("key$i",$i);
&& &$redis-&expire("key$i",3);
&& &$redis-&exec();
$time_end = microtime_float();
$run_time = $time_end - $time_
echo "用时 $run_time 秒\n";
//关闭连接
$redis-&close();
function microtime_float()
&& &list($usec, $sec) = explode(" ", microtime());
&& &return ((float)$usec + (float)$sec);
&&  问题出现了瓶颈,有好多公司需要海量数据处理,每秒5000次远不能满足需求,然后由于redis主从服务器上比memcache有更大的优势,
为了将来数据的着想,不得不使用redis,这时候出现了一种新的方式,即phpredis提供的pipline功能,该功能能够真正的将几条代码封装成
一次请求,从而大大提高了运行速度,50万次的数据执行只有了58秒。测试代码如下:redis4.php
$redis = new Redis();
$redis-&connect('127.0.0.1', 6379);
$time_start = microtime_float();
//保存数据
for($i = 0; $i & 100000; $i ++){
  $pipe=$redis-&pipeline();
&& &$pipe-&sadd("key$i",$i);
&& &$pipe-&expire("key$i",3);
&& &$replies=$pipe-&execute();
$time_end = microtime_float();
$run_time = $time_end - $time_
echo "用时 $run_time 秒\n";
//关闭连接
$redis-&close();
function microtime_float()
&& &list($usec, $sec) = explode(" ", microtime());
&& &return ((float)$usec + (float)$sec);
  运用这个操作可以非常完美的将赋值操作和设置过期时间操作打包到一个请求去执行,大大提高了运行效率。
redis安装:http://mwt198668./blog/static//
memcache安装:http://blog.csdn.net/barrydiu/article/details/3936270
redis设置主从服务器:/fuwuqi/fuwuqijiqunyuanquan/-7117.html
memcache设置主从服务器:/yuanermen/archive//2051153.html
本文來自:http://blog.csdn.net/a/article/details/7594814
阅读(...) 评论()

我要回帖

更多关于 thinkphp 数据库缓存 的文章

 

随机推荐