关于mongodb ,redis,memcache之间见不乱理还乱的关系和做用

先说我本身用的状况:php

最早用的memcache ,用于键值对关系的服务器端缓存,用于存储一些经常使用的不是很大,但须要快速反应的数据html


而后,在另外一个地方,要用到redis,而后就去研究了下redis. 一看,显示本身安装了php扩展,由于有服务器上的redis服务端,本身本地就没有安装,其实用法和memcache基本同样,可能就是几个参数有所不 同。固然 它们缓存的效果也不同,具体的哪里不同,一下就是一些资料,和本身的总结redis



一、 Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其余东西,例如图片、视频等等。
二、 数据类型--Memcache在添加数据时就要指定数据的字节长度,例如:
  set key3 0 0 8
  lxsymcto
  STORED
而redis不须要,如:redis 127.0.0.1:6379>set key2 "lxsymblog"
  OK
  redis 127.0.0.1:6379>get key2
  "lxsymblog"
三、虚拟内存--Redis当物理内存用完时,能够将一些好久没用到的value 交换到磁盘
四、过时策略--memcache在set时就指定,例如set key1 0 0 8,即永不过时。Redis能够经过例如expire 设定,例如expire name 10
五、分布式--设定memcache集群,利用magent作一主多从;redis能够作一主多从。均可以一主一从
六、存储数据安全--memcache挂掉后,数据没了;redis能够按期保存到磁盘(持久化)
七、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后能够经过aof恢复

算法

从如下几个维度,对redismemcachemongoDB 作了对比,欢迎拍砖mongodb

1、性能数据库

都比较高,性能对咱们来讲应该都不是瓶颈缓存

整体来说,TPS方面redismemcache差很少,要大于mongodb安全

2、操做的便利性服务器

      memcache数据结构单一网络

      redis丰富一些,数据操做方面,redis更好一些,较少的网络IO次数

       mongodb支持丰富的数据表达,索引,最相似关系型数据库,支持的查询语言很是丰富

3、内存空间的大小和数据量的大小

       redis2.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不支持,一般用在作缓存,提高性能;

          MongoDB1.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的测试代码以下:

<?php

$mem = new Memcache;

$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_start;

echo "用时 $run_time 秒\n";

function microtime_float()

{

    list($usec, $sec) = explode(" ", microtime());

    return ((float)$usec + (float)$sec);

}

?>

  redis的测试代码以下:redis1.php 此代码大概须要10秒左右

<?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);

}

$time_end = microtime_float();

$run_time = $time_end - $time_start;

echo "用时 $run_time 秒\n";

//关闭链接

$redis->close();

 

function microtime_float()

{

    list($usec, $sec) = explode(" ", microtime());

    return ((float)$usec + (float)$sec);

}

?>

  若是须要在设置键值的同时设置过时时间,大概执行须要20秒左右,测试代码以下:redis2.php

<?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_start;

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

<?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_start;

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

<?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_start;

echo "用时 $run_time 秒\n";

//关闭链接

$redis->close();

 

function microtime_float()

{

    list($usec, $sec) = explode(" ", microtime());

    return ((float)$usec + (float)$sec);

}

?>

  运用这个操做能够很是完美的将赋值操做和设置过时时间操做打包到一个请求去执行,大大提升了运行效率。

 

redis安装:http://mwt198668.blog.163.com/blog/static/48803692201132141755962/

memcache安装:http://blog.csdn.net/barrydiu/article/details/3936270

redis设置主从服务器:http://www.jzxue.com/fuwuqi/fuwuqijiqunyuanquan/201104/15-7117.html

memcache设置主从服务器:http://www.cnblogs.com/yuanermen/archive/2011/05/19/2051153.html

相关文章
相关标签/搜索