Redis与Memcache的对比

Redis与Memcache的对比

1、 Redis和Memcache都是将数据存放在内存中,都是内存数据库。

不过memcache还可用于缓存其他东西,例如图片、视频等等

2、 数据类型–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"

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恢复

8、由于Redis只使用单核,而Memcached可以使用多核

平均每一个核上Redis在存储小数据时比Memcached性能更高
相关解释,转自[知乎]
比如CPU是8核8线程的,用memcache一定会被分解成八份,原子化后,由8个进程分别处理。
memcache分解的时间是A,memcache处理的时间是B。

假若Redis和memcache处理效率一样,那么A+B是memcache的总时间,8B就是Redis的总时间。

处理小文件的时候,小文件处理时间短,memcache分解的时间A>7B,Redis效率高。

随着文件越来越大,随着Redis处理的时间越来越长,当7B>A时(大文件),这时候memcache效率更高。

通俗地讲,你是一个老板,把一件小事分给8个人做,可能还不如一个人做得好,把时间浪费在开会分配上了。

但是你把一件大事分给8个人,原来需要8个小时的事情,1个小时就搞定了。

9、应用场景不一样

  • Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;
  • Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等

从以下几个维度,对redis、memcache、mongoDB 做了对比,欢迎拍砖

1、性能

总体来讲,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、数据一致性(事务支持)

  • redis事务支持比较弱,只能保证事务中的每个操作连续执行
  • memcache 在并发场景下,用cas保证一致性
  • mongoDB不支持事务

7、数据分析

mongoDB内置了数据分析的功能(mapreduce),其他不支持  

8、应用场景

  • redis:数据量较小的更性能操作和运算上
  • memcache:用于在动态系统中减少数据库负载,提升性能;
    做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)
  • MongoDB:主要解决海量数据的访问效率问题

经过对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秒左右,测试代码如下
<?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);
}

事务,通过multi原子性的将一段代码块依次执行,从而达到一个完整功能模块的执行。
不幸的是通过测试发现,采用multi方式执行代码时并没有减少请求次数,
相反在执行multi指令和exec指令时都要发送请求,
从而将运行时间变成了原来的四倍,即四条指令的运行时间。

<?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);
}
redis主从服务器上比memcache有更大的优势,且有可执行连贯操作的管道功能
redis的管道功能。测试代码如下
<?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);
}

运用这个操作可以非常完美的将赋值操作和设置过期时间操作打包到一个请求去执行,大大提高了运行效率。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值