Redis简介
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。
图1.1(图片来源于百度百科)
Redis的诞生
为了在不升级VPS(Virtual Private Server 虚拟专用服务器)的前提下,解决网站的负载问题,Salvatore Sanfilippo(Redis的创建人,网名:antirez)打算自己写一个具有列表结构的内存数据库,这个数据库原型支持O(1)复杂的推入和弹出操作,并且将数据存储在内存,而不是在硬盘中,所以程序的性能不会受到硬盘的输入输出限制,可以快速的执行对列表的推入和弹出操作。通过实验,这个数据库原型可以在不升级VPS的前提下,解决网站的负责问题,于是Salvatore Sanfilippo使用C语言重写了这个内存数据库,并加上了持久化功能,Redis就这样诞生了!
Redis的演进
图1.2为什么使用Redis
-
Redis内存存储,速度更快
图1.3 - 独特的键值对模型
很多数据库只能处理一种数据结构:
- SQL 数据库 —— 表格
- Memcached —— 键值对数据库,键和值 都是字符串
- CouchDB、MongoDB —— 由 JSON/BSON 组成的文档
Redis 也是键值对数据库,但和 Memcached 不同的是,Redis 的值不仅可以是字符串,它还 可以其他五种数据结构中的任意一种。通过选用不同的数据结构,用户可以使用 Redis 解决各式各样的问题。
- 优点
- 持久化功能
- 读写性能优异
- 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
- 数据结构丰富
- 集群
Redis 的使用
基本数据类型
- 字符串
字符串是Redis中最简单的数据类型,既可以存储数字,也可以二进制,还可以存储文字。Redis为这几种类型的值设置了不同的操作命令,让用户可以针对不同的值做不同的处理。
为字符串设置值(SET key values)
将字符串键key的值设置为value,命令返回OK表示设置成功,如果字符串键key已经存在,那么就会用新的value覆盖以前的value(类似Java中的Map)。例如
SET msg "HELLO"
为键值为msg的赋值HELLO,此时msg的值为HELLO,如果此时进行下面的操作,会将进的值覆盖掉原来的值,即 msg的值现在变为了 HELLO WORLD。
SET msg "HELLO WORLD"
为字符串设置值(SET key values[NX][XX])
SET命令还支持可选的NX选项和XX选项
- 如果给定了 NX 选项,那么命令在键 key 不存在的情况下,才进行设置操作;如果键 key 已经存 在,那么 SET ... NX 命令不做动作(不会覆盖旧值)。
- 如果给定了 XX 选项,那么命令仅在键 key 已经存在的情况下,才进行设置操作;如果键 key 不存 在,那么 SET ... XX 命令不做动作(一定会覆盖旧值)。
1)SET str "str" XX
2)SET str "str" NX
3)SET str "str" NX
4)SET str "str" XX
在上面的四条代码中,可以看到,运行成功的是2)和4),1)错误的原因是由于键str不存在,指定XX选项导致设置失败,3)的错误原因是键已经存在,指定NX选项导致设置失败。
获取字符串的值(GET key)
使用如下所示的代码就可以获取到Redis的值
GET msg
缓存程序的 API 及其实现
API | 效果 | 实现 |
---|---|---|
Cache(client) | 设置缓存程序使用的客户端。 | |
Cache.put(name, content) | 把指定的内容放到缓存里面,并使用 name 来 命名它,以便之后取出。 | 调用 SET 命令。 |
Cache.get(name) | 从缓存中取出以 name 命名的内容。 | 调用 GET 命令。 |
同时设置或获取多个字符串键的
命令 | 效果 |
---|---|
MSET key value [key value ...] | 一次为一个或多个字符串键设置 值,效果和同时执行多个 SET 命 令一样。 命令返回 OK 。 |
MGET key [key ...] | 一次返回一个或多个字符串 键的 值,效果和同时执行多个 GET 命 令一样。 |
追加内容到字符串末尾(APPEND key value)
将值value加入到字符串键key已存储内容的末尾,例如
1)SET msg "HELLO"
2) APPEND msg “ WORLD”
当1)完成时候,字符串键msg的值为HELLO,当执行完 步骤2)时,字符串键msg的值已经变为HELLO WORLD
返回值的长度(STRLEN key)
STRLEN 关键词是用来返回字符串键 key 储存的值的长度,如下所示。
1) SET msg "HELLO"
2) STRLEN msg //返回值为5
设置新的值并返回旧值(GETSET key new-value)
将字符串键的值设置为new-value,并返回字符串键的旧值old-value。
SET str "old-value"
GETSET str "new-value"
范围取值(GETRANGE key start end)
SET msg "hello"
GETRANGE msg 1 4
返回结果: ello
增加或减少数字的值(整数)
命令 | 效果 |
---|---|
INCRBY key increment | 将key所存储的值加上增量increment,命令完成后返回操作执行后的value值 |
DECRBY key increment | 将key所存储的值减去增量increment,命令完成后返回操作执行后的value值 |
如果执行上述两种命令时,当key不存在的时候,key所对应的value值会设置为0,然后在进行操作。
加一或者减一(整数)
命令 | 效果 |
---|---|
INCR key | 加一 |
DECR key | 减一 |
使用案例:计数器,点击次数,访问量,点赞和取消点赞。
RedisCacheUtil工具类
在平时开发的工程中,我们不可能反复的写GET、SET反复获取值、设置值,这时候就需要一个工具类了,如下所示:
import redis.clients.jedis.JedisCluster;
public class RedisCacheUtil {
private static JedisCluster jedisCluster;
public JedisCluster getJedisCluster() {
return jedisCluster;
}
public void setJedisCluster(JedisCluster jedisCluster) {
RedisCacheUtil.jedisCluster = jedisCluster;
};
/**
* 指定String key 删除
* @param key
*/
public static void delete(String key) {
jedisCluster.del(key);
}
/**
* 取出 缓存 数据
* @param key
* @return
*/
public static String get(String key) {
String value = jedisCluster.get(key);
return value;
}
/**
* 存入缓存数据
* @param key
* @param value
*/
public static void set(String key,String value) {
jedisCluster.set(key, value);
}
/**
* 删除 key 存贮
* @param key
* @return
*/
public static Long del(String key) {
Long value = jedisCluster.del(key);
return value;
}
/**
* 设置 过期时间 单位秒
* @param key
* @param value
* @param seconds
* @return
*/
public static void setTimeSecond(String key,String value,int seconds ) {
jedisCluster.setex(key, seconds, value);
}
/**
* 设置 过期时间 单位毫秒
* @param key
* @param value
* @param milliseconds
* @return
*/
public static void setTimeMilliseconds(String key,String value,long milliseconds ) {
jedisCluster.psetex(key, milliseconds, value);
}
/**
* 设置 过期时间 以天为单位
* @param key
* @param value
* @param day
* @return
*/
public static void setTimeDay(String key,String value,int day ) {
jedisCluster.psetex(key, day*24*60*60, value);
}
/**
* 设置 过期时间 以小时为单位
* @param key
* @param value
* @param Hour
* @return
*/
public static void setTimeHour(String key,String value,int Hour ) {
jedisCluster.psetex(key, Hour*60*60, value);
}
/**
* 设置 过期时间 以分钟为单位
* @param key
* @param value
* @param minute
* @return
*/
public static void setTimeMinute(String key,String value,int minute ) {
jedisCluster.psetex(key, minute*60, value);
String string = jedisCluster.get(key);
System.out.println(string);
}
/**
* 自增:计数
* @param key 已保存的key值
*/
public static void incr(String key){
jedisCluster.incr(key);
}
}
通过这个工具栏,我们就可以使用不同的方法,获取到不同的值,或者设置、覆盖、删除操作。
结束语
蛐蛐目前也是刚开始学习Redis,后续还会持续更新,如果各位有不同意见,欢迎指正!共勉!!!
网友评论