Redis实战总结(一)
来源:互联网 发布:星星知我心原唱是谁 编辑:程序博客网 时间:2024/06/05 08:15
* 序言
最近花了一些时间将《Redis实战》,和网上关于Redis的一些博客研究了下。针对这段时间的学习做一个总结,内容如下:
- Redis介绍
- Redis的数据结构及命令
- Redis的管道及PUB/SUB机制
- Redis配置、复制及持久化
- Redis高可用性
- Redis内存优化及Lua脚本编程
其中第一篇博客介绍1、2两部分,第二篇博客介绍3部分,第三篇博客介绍4、5两部分,第四篇博客介绍6部分。
1. Redis介绍
Redis是一个开源(遵守BSD协议),基于内存的key-value高性能存储系统,可以用作数据库、速缓存和消息队列代理。它支持字符串(STRING)、哈希表(HASH)、列表(LIST)、集合(SET)、有序集合(ZSET)等数据结构。
Redis 相对于其它 key - value 缓存产品,比如memorycache(分布式缓存),Guavacache(本地缓存)有下面三大特点:
- Redis支持数据持久化,可以将内存中的数据存储在磁盘中,重启的时候能够还原Redis环境。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据备份,即master-slave(主从)模式的数据备份(不支持主主复制)。
2. Redis的数据结构
Redis可以存储键与5种不同数据结构类型之间的映射,这五种数据结构类型为:STRING,HASH,LIST,SET,ZSET。每种数据结构都有自身的操作命令,当然也有一部分操作命令是对这些数据结构都通用的,比如DEL,RENAME等。
String
在Redis里面,字符串可以存储以下三种类型:
- 字符串
- 整数
- 浮点数
Redis常见字符串命令:
HASH
和字符串一样,散列存储的值既可以是字符串又可以是数字值,同样对于数字值可以进行自增或自减。
Redis中常见散列命令:
LIST
Redis列表(链式存储结构)允许用户从列表额两端推入或者弹出元素,以获取元素,以及执行各种常见的列表操作。
Redis中常见列表命令:
Redis列表还存在一些阻塞式弹出推入命令,可以应用在消息传递和任务队列等场景中。
SET
Redis的集合以无序的方式来存储多个各不相同的元素,用户可以很方便的添加元素,移除元素以及判断元素是否存在与集合中。
Redis中常见集合命令:
ZSET
有序集合和散列存储着键与值之间映射类似,也存在成员和分值(正常以时间或者值得大小作为分值)的映射,并且提供了分值的处理命令。
Redis中常见有序集合命令:
当然有序集合还有许多比较有用的命令,就不一一列举了。
SORT命令
SORT命令可以实现按照给定的选项,对输入的列表,集合,有序集合,散列进行排序,返回排序后的结果。
3.Redis其他命令
Redis除了上述数据结构操作命令外,还有发布订阅命令,实现基本事务特性的MULTI命令和EXEC命令,自动过期EXPIRE命令。下面介绍这些命令,其中发布订阅命令发在下篇博客中介绍。
MULTI和EXEC命令
在Redis中,有时可能需要同时处理多个命令,即需要将这些命令一个事物,一次性提交给Redis。Redis为实现这种机制,引进了multi和exec命令。首先需要先执行multi命令,然后在输入我们需要执行的命令,最后在执行exec命令。
EXPIRE命令
在使用Redis存储数据时,有些数据存储一段时间后就不会再使用了,比如不同系统之间的会话密钥(保证两个小时后自动失效),因而Redis引入了一种“带有生存时间”特殊键。如果为一个键设置了生存时间,则到了生存时间,Redis会自动的(应用程序透明,由Redis线程自己负责)将改建删除。
常见的几个命令:
4. 在JAVA中实现Redis连接池
在Java中使用Jedis.jar操作Redis,下面给出demo演示在Java中如何构建Redis缓存连接池,并给出散列(MAP)相关命令的代码实现。
新建Maven工程,在pom.xml中添加依赖(maven和log4j)
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
配置log4j,log4j.properties
#config root loggerlog4j.rootLogger = DEBUG,system.outlog4j.appender.system.out=org.apache.log4j.ConsoleAppenderlog4j.appender.system.out.layout=org.apache.log4j.PatternLayoutlog4j.appender.system.out.layout.ConversionPattern=MINAServer Logger-->%5p{%F:%L}-%m%n#config this Project.file loggerlog4j.logger.thisProject.file=INFO,thisProject.file.outlog4j.appender.thisProject.file.out=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.thisProject.file.out.File=logContentFile.loglog4j.appender.thisProject.file.out.layout=org.apache.log4j.PatternLayout
JedisUtil类:
package util;import org.apache.log4j.Logger;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import java.util.Map;import java.util.Set;/** * 搭建Redis缓存连接池 * @author guweiyu */public class JedisUtil { private static Logger logger = Logger.getLogger(JedisUtil.class.getName()); // 创建JedisPoll实例 private static JedisPool jedisPool; // 设置Jedis连接相关参数 // Redis服务器IP,端口号 private static String REDIS_ADDRESS = "127.0.0.1"; private static Integer REDIS_PORT = 6379; // 最大连接数, 默认8个 private static Integer MAX_TOTAL = 8; // 最大空闲连接数, 默认8个 private static Integer MAX_IDLE = 8; // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1) private static Integer MAX_WAIT_MILLIS = 10000; // Re private static Integer TIMEOUT = 10000; /** * 初始化Redis缓存连接池 */ public static void init() { try { // 构建Redis配置 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(MAX_TOTAL); config.setMaxIdle(MAX_IDLE); config.setMaxWaitMillis(MAX_WAIT_MILLIS); // 创建Redis缓存连接池子 jedisPool = new JedisPool(config, REDIS_ADDRESS, REDIS_PORT, TIMEOUT); logger.info("Redis连接池初始化成功"); } catch (Exception e) { logger.error("Redis连接池初始化失败", e); e.printStackTrace(); } } /** * 关闭redis连接实例 * @param jedis */ private static void safeReturn(Jedis jedis) { if (jedis != null) { jedis.close(); } } /** * 判断散列中是否存在键 * @param key * @param field * @return */ public static boolean hexist(String key, String field) { Jedis jedis = jedisPool.getResource(); try { return jedis.hexists(key, field); } finally { safeReturn(jedis); } } /** * 在散列里批量关联起给定的键值对,并设置超时时间,单位秒 * @param key * @param hash * @param timeout */ public static void setHash(String key, Map<String, String> hash, int timeout) { Jedis jedis = jedisPool.getResource(); try { jedis.hmset(key, hash); jedis.expire(key, timeout); } finally { safeReturn(jedis); } } /** * 在散列里批量关联起给定的键值对 * @param key * @param hash */ public static void setHash(String key, Map<String, String> hash) { Jedis jedis = jedisPool.getResource(); try { jedis.hmset(key, hash); } finally { safeReturn(jedis); } } /** * 在散列里关联起给定的键值对 * @param key * @param field * @param value */ public static void addHashValue(String key, String field, String value) { Jedis jedis = jedisPool.getResource(); try { jedis.hset(key, field, value); } finally { safeReturn(jedis); } } /** * 获取指定散列键的值 * @param key * @param field * @return */ public static String getHashValue(String key, String field) { Jedis jedis = jedisPool.getResource(); try { return jedis.hget(key, field); } finally { safeReturn(jedis); } } /** * 获取散列包含的所有键值对 * @param key * @return */ public static Map<String, String> hgetAll(String key) { Jedis jedis = jedisPool.getResource(); try { return jedis.hgetAll(key); } finally { safeReturn(jedis); } } /** * 删除给定的键(适用于所有类型) * @param key */ public static void del(String key) { Jedis jedis = jedisPool.getResource(); try { jedis.del(key); } finally { safeReturn(jedis); } }}
主程序测试:
import org.apache.log4j.Logger;import util.JedisUtil;import java.util.HashMap;public class Application { private static Logger logger = Logger.getLogger(Application.class); private static String MAP_KEY_PREFIX = "hash_map_prefix_"; private static String TEST1 = "test1"; private static String TEST2 = "test2"; private static String TEST3 = "test3"; private static String TEST4 = "test4"; public static void main (String[] args) throws Exception { logger.info("Main Application is starting"); JedisUtil.init(); String key1 = new StringBuilder(MAP_KEY_PREFIX).append(TEST1).toString(); HashMap<String, String> test1Map = new HashMap<>(); test1Map.put("user", "guweiyu"); JedisUtil.setHash(key1, test1Map, 5); logger.info("key["+key1+"]:"+JedisUtil.getHashValue(key1, "user")); logger.info("key["+key1+"]:"+JedisUtil.hgetAll(key1)); Thread.sleep(6000); logger.info("key["+key1+"]:"+JedisUtil.hgetAll(key1)); JedisUtil.del(key1); logger.info("key["+key1+"]:"+JedisUtil.hexist(key1, "user")); String key2 = new StringBuilder(MAP_KEY_PREFIX).append(TEST2).toString(); HashMap<String, String> test2Map = new HashMap<>(); test2Map.put("user", "hebaobao"); JedisUtil.setHash(key2, test2Map); logger.info("key["+key2+"]:"+JedisUtil.getHashValue(key2, "user")); logger.info("key["+key2+"]:"+JedisUtil.hgetAll(key2)); Thread.sleep(6000); logger.info("key["+key2+"]:"+JedisUtil.hgetAll(key2)); JedisUtil.addHashValue(key2, "mobino", "173"); logger.info("key["+key2+"]:"+JedisUtil.hgetAll(key2)); }}
程序运行结果:
持之以恒!!!!!
- Redis实战总结(一)
- redis 实战系列(一)
- Redis入门实战(一)
- Redis实战总结(二)
- Redis实战总结(三)
- Redis实战(一) 使用缓存合理性
- Redis实战(一) 使用缓存合理性
- redis实战教程(一)-分布式锁
- C# Redis实战(一)
- Redis总结(一)Redis安装
- Redis实战之征服 Redis + Jedis + Spring (一)
- Redis实战之征服 Redis + Jedis + Spring (一)
- Redis实战之征服 Redis + Jedis + Spring (一)
- Redis实战之征服 Redis + Jedis + Spring (一)
- Redis实战之征服 Redis + Jedis + Spring (一)
- Redis实战之Windows Redis 集群搭建(一)
- Redis实战之征服 Redis + Jedis + Spring (一)
- HTML实战项目总结(一)
- MongoDB 数据库创建删除、表(集合)创建删除、数据增删改查
- String与stringbuilder的效率差异
- spark第3天
- C语言实验——分割整数
- 图像目标检测与跟踪学习笔记(四)
- Redis实战总结(一)
- servlet实现车险管理系统
- RabbitMQ入门教程(十三):虚拟主机vhost与权限管理
- LeetCode Union-Find(并查集) 专题(一)
- boost 库的编译与链接
- Matrix67:什么是P问题、NP问题和NPC问题
- 撤销功能的实现——备忘录模式(四)
- 数字图像处理期中学习报告
- 开始前端-----第六篇