1,性能。
由于Redis只使用单核,而Memcached可以使用多核 。 所以平均每一个核上Redis在存储小数据时比Memcached性能更高。 而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。 【数据量小时,redis性能更高,反之,Memcached性能更高】。
2,内存使用效率。
使用简单的key-value存储的话, Memcached 的内存使用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存使用率会高于Memcached。
3,Redis支持服务器端的数据操作。
Redis相比Memcached, 拥有更多的数据结构和并支持更丰富的数据操作 , 通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。 这大大增加了网络IO的次数和数据体积 。 在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。
除此之外的一些区别,
1,集群。
设定memcached集群,利用magent做一主多从。都可以一主一从。
2,存储。
Redis和Memcached都是将数据存放在内存中,都是内存数据库,不过memcache还可以用于缓存其他东西。例如图片,视频等等。memcache把数据全部存在内存中。断电后会挂掉,数据不能超过内存大小。redis有部分存在硬盘上。这样能保证数据的持久性,支持数据的持久化。
3,备份恢复
memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复,Redis支持数据的备份,即master-slave模式的数据备份。
1),Memcached采用客户端-服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端Library可以用任何语言实现。
2),Redis内部的数据结构最终也会落实到key-Value对应的形式,不过从暴露给用户的数据结构来看,要比memcached丰富,除了标准的通常意义的键值对, Redis还支持List, Set, Hashes, Sorted Set。
3),性能方面,两者都有一些自己考虑和实现
Memcached,自身并不主动定期检查和标记哪些数据需要被淘汰,只有当再次读取相关数据时才检查时间戳,或者当内存不够使用需要主动淘汰数据时进一步检查LRU数据。
Redis
Redis为了减少大量小数据CMD操作的网络通讯时间开销RTT(Round Trip Time),支持pipeline和script技术。所谓的pipeline就是支持在一次通讯中,发送多个命令给服务器批量执行。 带来的代价是服务器端需要更多的内存来缓存查询结果 。
Redis内嵌了LUA解析器,可以执行lua脚本,脚本可以通过eval灯命令直接执行,也可以使用script load等方式上传到服务器端的script cache中重复使用。
二,Jedis三种工作模式的连接。
1,单机模式; 2,分片模式;3,集群模式。
1),
//初始化连接
private Jedis jedis=new Jedis("192.168.0.100", 6379);
jedis.set("a","b");
jedis.hmset(key, hash);
2),
GenericObjectPoolConfig config=new GenericObjectPoolConfig();
config.setMaxIdle(32);
config.setMinIdle(12);
config.setTestOnBorrow(true);
config.setTestOnReturn(rtrue);
config.setTestWhileIdle(true);
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
for (int i = 0; i < shareds.size(); i++) {
shards.add(new JedisShardInfo("192.168.0.100", 6379, 200));
}
// 构造池
ShardedJedisPool shardedJedisPool= new ShardedJedisPool(config, shards);
ShardedJedis jedis=shardedJedisPool.getResource();
jedis.set("a","b");
jedis.hmset(key, hash);
3),
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
for (int i = 0; i < shareds.size(); i++) {
jedisClusterNodes.add(new HostAndPort("192.168.0.100",6379));
}
// 构造池
BinaryJedisCluster cluster= new BinaryJedisCluster(jedisClusterNodes);
cluster.set("a","b");
cluster.hmset(key, hash);
……
BinaryJedisCluster.java是为了让jedis支持byte数组形式value重写的一个类,
public class BinaryJedisCluster extends JedisCluster {
public String set(final String key, final byte[] value) {
return new JedisClusterCommand<String>(connectionHandler, timeout,
maxRedirections) {
public String execute(Jedis connection) {
return connection.set(SafeEncoder.encode(key), value);
}
}.run(key);
}
public byte[] getBytes(final String key) {
return new JedisClusterCommand<byte[]>(connectionHandler, timeout,
maxRedirections) {
public byte[] execute(Jedis connection) {
return connection.get(SafeEncoder.encode(key));
}
}.run(key);
}
public Set<byte[]> zrevrangeByScoreBytes(final String key, final double max,
final double min, final int offset, final int count) {
return new JedisClusterCommand<Set<byte[]>>(connectionHandler, timeout,
maxRedirections) {
public Set<byte[]> execute(Jedis connection) {
return connection.zrevrangeByScore(SafeEncoder.encode(key),
max, min, offset, count);
}
}.run(key);
}
public Set<byte[]> zrevrangeByScoreBytes(final String key, final String max,
final String min, final int offset, final int count) {
return new JedisClusterCommand<Set<byte[]>>(connectionHandler, timeout,
maxRedirections) {
public Set<byte[]> execute(Jedis connection) {
return connection.zrevrangeByScore(SafeEncoder.encode(key),
SafeEncoder.encode(max), SafeEncoder.encode(min), offset, count);
}
}.run(key);
}
public Long linsert(final String key, final LIST_POSITION where,
final byte[] pivot, final byte[] value) {
return new JedisClusterCommand<Long>(connectionHandler, timeout,
maxRedirections) {
public Long execute(Jedis connection) {
return connection.linsert(SafeEncoder.encode(key), where,
pivot, value);
}
}.run(key);
}
public Long lpushx(final String key, final byte[]... string) {
return new JedisClusterCommand<Long>(connectionHandler, timeout,
maxRedirections) {
public Long execute(Jedis connection) {
return connection.lpushx(SafeEncoder.encode(key), string);
}
}.run(key);
}
public Long rpushx(final String key, final byte[]... string) {
return new JedisClusterCommand<Long>(connectionHandler, timeout,
maxRedirections) {
public Long execute(Jedis connection) {
return connection.rpushx(SafeEncoder.encode(key), string);
}
}.run(key);
}
public List<byte[]> blpopBytes(final String arg) {
return new JedisClusterCommand<List<byte[]>>(connectionHandler,
timeout, maxRedirections) {
public List<byte[]> execute(Jedis connection) {
return connection.blpop(SafeEncoder.encode(arg));
}
}.run(null);
}
public List<byte[]> brpopBytes(final String arg) {
return new JedisClusterCommand<List<byte[]>>(connectionHandler,
timeout, maxRedirections) {
public List<byte[]> execute(Jedis connection) {
return connection.brpop(SafeEncoder.encode(arg));
}
}.run(null);
}
}