什么是Redis
Redis:Remote Dictionary Server(远程字典服务器)。是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据结构服务器。
redis的特点
- Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库系统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知综合性能最快的Key-Value DB。
- Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。
- Redis是单进程单线程的,这样利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
- Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
redis的优势
速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
支持丰富数据类型,支持string,list,set,sorted set,hash
支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
redis的数据存储和读写模式
- Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。可通过设置最大使用内存,则数据已有记录数达到内存限值后不能继续插入新值。
- redis支持主从的模式:Master会将数据同步到slave,而slave不会将数据同步到master。Slave启动时会连接master来同步数据。这个典型的分布式读写分离模型,利用master来插入数据,slave提供检索服务,有效减少单个机器的并发访问数量。
redis集群的缺陷及解决方案
- 集群的读写分离模型通过增加Slave DB和Master DB的数量,整个集群的读和写的可用性都非常高。但是不管是Master还是Slave,每个节点都必须保存完整的数据,如果在数据量很大的情况下,集群的扩展能力还是受限于单个节点的存储能力,而且对于Write-intensive类型的应用,读写分离架构并不适合。
- 数据分片模型用于解决读写分离模型的缺陷,可以将每个节点看成都是独立的master,然后通过业务实现数据分片。将每个master设计成由一个master和多个slave组成的模型。
redis数据类型及常用语句:
string:
String是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。String类型是二进制安全的:意思是redis的String可以包含任何数据,比如jpg图片或者序列化的对象。String类型是redis最基本的数据类型,一个redis中字符串value最多可以是512M。
incr key ==>某个键自增1
decr key ==>某个键自减1
incrby key k ==>某个键自增k
decrby key k ==>某个键自减k
set key value ==>不论键是否存在都加(insert and update)
setnx key value ==>键不存在才加进去(insert)
set key value xx ==>键存在才加进去(update)
mget key1 key2 key3 ==>获取多个key的value
mset key1 value1 key2 value2 key3 value3 ==>设置多个键值对
getset key newvalue ==>给这个key赋新的值,该条命令返回的是旧的value
append key value ==>将value追加到旧的value,以value1,value2的形式
strlen key ==>返回key对应的value的字符串长度(UTF8中,一个中文占两位)
incrbyfloat key f ==>某个键自增f,f可以为flsoat类型
getrange key start end ==>得到对应的value的start到end之间的值
setrange key index value ==>指定index位置设定值
hash:
Redis hash是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似java里面的Map<String,Object>
hget key filed ==>获取key的filed的value
hset key filed value ==>设置key的filed的value
hdel key filed ==>删除key的filed
hgetall key ==>获取key的所有filed和对应的value
hvals key ==>获取key对应的所有的filed的value
hkeys key ==>获取key对应的所有的filed
hexists key filed ==>判断某个key是否存在某个filed
hlen key ==>获取key的filed的数量
hmget key filed1 filed2 filed3 ==>获取某个key一批filed的value
hmset key filed1 value1 filed2 value2 ==>设置某个key一批filed的value
list:
Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个链表。
lpush key value1 value2 value3 ==>从列表左端插入值
rpush key value1 value2 value3 ==>从列表右端插入值
linsert key before|after value newValue
lpop key ==>从左边弹出一个value
rpop key ==>从右边弹出一个value
lrem key count value ==>count=0 删除对应的value中所有的value值
==>count>0 从左到右删除对应的value中的count个value值
==>count<0 从右到左删除对应的value中的count个value值
ltrim key start end ==>保留key对应的value的第start到end个
lrange key start end ==>获取key对应value的第start到end个
lindex key index ==>获取key对应value的第index的value
llen key ==>获取key对应的value的长度
lset key index newValue ==>设置key对应的value的第index位为newValue
blpop key timeout ==>左弹出阻塞timeout间段
brpop key timeout ==>右弹出阻塞timeout间段
set:
Redis的Set是String类型的无序集合,它是通过HashTable实现的。
sadd key value1 value2 ==>添加key对应的value值,value若重复则失败
sinter key1 key2 key3 ==>集合交集
sdiff key1 key2 key3 ==>集合不同的集合
sunion key1 key2 key3 ==>集合并集
scard key ==>集合大小
sismember key value ==>存在1,不在0
srandmember key count ==>随机选出集合中count个元素
spop key ==>随机弹出一个元素,弹出后,该元素在集合中消失
smembers key ==>返回集合中所有元素
zset:
Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数(score)。Redis根据score进行从小到大的排序。zset的成员唯一的,但分数(score)却可以重复。
zadd key score value ==>添加key对应的value值,并且附上权值score
zrem key value1 value2 ==>删除value值
zscore key value ==>返回value对应的权值
zincrby key increScore value ==>给key对应的value集合中的value对应的score增加increScore的值
zcard key ==>返回集合总数
zrank key value ==>返回集合中value的排名
zrange key start end [withscores] ==>获取排名start到end之间的value集合
zrangebyscore key minScore maxScore [withscores] ==>获取权值在minScore到maxScore之间的value集合
zcount key minScore maxScore ==>获取分数在minScore到maxScore之间的value集合的个数
zremrangebyrank key start end ==>删除排名start到end之间的value集合
zremrangebyscore key minScore maxScore ==>删除分数在minScore到maxScore之间的value
none:
redis的详细命令文档 http://doc.redisfans.com/
Redis的安装和启动(Linux)
安装
这里我下载的是 redis-3.2.1.tar.gz
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
解压
tar xzf redis-5.0.5.tar.gz
进入目录,安装
cd redis-5.0.5
make
make install PREFIX=/usr/local/redis-5.0.5
配置环境变量
启动redis服务器(推荐指定配置文件启动):
在redis-5.0.5目录下,建立一个config的文件夹,把默认的redis.conf拷贝到这个目录下
去掉redis.conf中的注释和空行,并复制为redis-6380.conf
grep -v “^#” redis.conf | grep -v “^$” >> redis-6380.conf
将daemonize no改为daemonize yes
将port 6379改为port 6380
运行该配置文件
redis-server redis-6380.conf
查看redis服务器是否运行(看到6380端口的redis进程存在即已运行)
ps aux | grep redis
redis客户机连接
redis-cli -h 127.0.0.1 -p 6380
关闭redis服务器
redis-cli -p 6380 shutdown
SSM整合redis
有一个搭好初步框架的SSM项目(这里不多做介绍)
配置pom.xml中加入依赖
<!--redis相关 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.6.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
建立redis.properties文件,设置redis连接参数
redis.host=***.***.***.*** # 你的redis的地址
redis.port=**** # 你的redis的端口
redis.pass=**** # 你的redis的密码
redis.maxIdle=200
redis.maxActive=1024
redis.maxWait=10000
redis.testOnBorrow=true
配置redis文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 连接池基本参数配置,类似数据库连接池 -->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxActive}"/>
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- 连接池配置,类似数据库连接池 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<property name="hostName" value="${redis.host}"></property>
<property name="port" value="${redis.port}"></property>
<property name="password" value="${redis.pass}"></property>
<property name="poolConfig" ref="poolConfig"></property>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 序列化方式 建议key/hashKey采用StringRedisSerializer -->
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<!-- 开启REIDS事务支持 -->
<property name="enableTransactionSupport" value="false" />
</bean>
<!-- 对string操作的封装 -->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<constructor-arg ref="jedisConnectionFactory" />
<!-- 开启REIDS事务支持 -->
<property name="enableTransactionSupport" value="false" />
</bean>
</beans>
applicationContext.xml中注入redis.xml的配置
<import resource="classpath*:/spring/spring-redis.xml"/>
我的项目在resources下建立spring的文件夹,将spring的其他配置放在里面
写一个测试方法验证redis的连通性
/**
* Created by Administrator on 2020-1-23.
*/
@RunWith(SpringJUnit4ClassRunner.class)
//告诉junit spring配置文件
@WebAppConfiguration
@ContextConfiguration({"classpath:applicationContext.xml"})
public class TestDAO {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
try{
redisTemplate.opsForValue().set("test", "测试");
System.out.println("value:"+redisTemplate.opsForValue().get("test"));
}catch(Exception e){
System.out.println("Redis-error");
}
}
}
完成redis的工具类
这里仅以缓存中构建key为例,redisTemplate的API可以参考博客
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* redis工具类
*/
@SuppressWarnings("unchecked")
public class RedisUtil {
@Autowired
private static RedisTemplate<String, Object> redisTemplate;
@Autowired
private static StringRedisTemplate stringRedisTemplate;
private static String CACHE_PREFIX;
/**
* 构建缓存key值
* @param key 缓存key
* @return
*/
private static String buildKey(String key) {
if (CACHE_PREFIX == null || "".equals(CACHE_PREFIX)) {
return key;
}
return CACHE_PREFIX + ":" + key;
}
}
去自己工程中根据自己的业务逻辑编写代码
参考博文:https://www.jianshu.com/p/9e144509bdcb