redis
配置文件
redis.windows.conf
主要设置
# 端口
port 6379
# 访问的IP
bind 127.0.0.1
# 默认数据库数量
databases 16
# rdb策略
save 900 1
save 300 10
save 60 10000
# 访问密码
requirepass root
# 开启aop
appendonly yes
# aof策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
运行
命令 :redis-server.exe redis.windows.conf
运行exe 并加载conf配置文件
运行画面
连接redis
另开一个窗口
连接命令:redis-cli.exe -h 127.0.0.1 -p 6379 -a root
-h 目标redis数据库的IP
-p 目标redis数据库的端口
-a目标redis数据库的密码
操作
添加操作
查询操作
Jedis
java redis连接
jar包
简单添加 查找操作
//创建连接 设置目标IP、端口、密码
Jedis j=new Jedis("127.0.0.1",6379);
j.auth("root");
//添加一行string数据
j.set("uname", "myname");
j.close();
这行数据已经被添加进redis数据库了
查询刚才添加的数据
//根据key取数据
String value=j.get("uname");
System.out.println(value);
j.close();
运行结果
Jedis分片连接池
开启集群redis数据库服务器
这里我们开启2个redis,模拟集群redis数据库服务器
创建2份redis.windows.conf
,修改其中一份的端口
# 端口
port 6379
1、配置连接设置
2、创建每个redis数据库连接信息
3、将连接信息add进数组
4、使用连接设置、连接信息 创建连接池对象
//连接池设置
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(1000);
config.setMaxIdle(100);
//连接信息
JedisShardInfo info1=new JedisShardInfo("127.0.0.1", 6378);
info1.setPassword("root");
JedisShardInfo info2=new JedisShardInfo("127.0.0.1", 6379);
info2.setPassword("root");
//List
List<JedisShardInfo> list=new ArrayList<>();
list.add(info1);
list.add(info2);
//连接池 通过配置、连接信息创建连接池
ShardedJedisPool pool=new ShardedJedisPool(config, list);
//获取连接对象
ShardedJedis resource=pool.getResource();
集群环境下无法使用多键命令
测试
添加100条数据
//向数据库添加100条键值对
for(int i=0;i<100;i++) {
resource.set("key"+i, "value"+i);
}
resource.close();
结果
连接池对象均衡分配给了2个分片
spring集成
1、在spring中引入
spring-config.xml
配置文件
<!-- redis集成配置-->
<import resource="classpath:redis-config.xml"/>
redis-config.xml
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
<!-- 如果外部配置文件数据出错 保证代码继续运行 -->
<property name="ignoreUnresolvablePlaceholders" value="true"></property>
</bean>
<!-- 连接池设置 -->
<bean id="poolconfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="minIdle" value="${redis.pool.minIdle}" />
<property name="lifo" value="${redis.pool.lifo}" />
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="testOnReturn" value="true" />
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="false" />
<!-- 表示一个对象至少停留在idle状态的最短时间;然后才能被idle object evitor扫描并驱逐 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
</bean>
<!-- 连接信息 -->
<bean id="sharedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="poolconfig"></constructor-arg>
<constructor-arg index="1">
<list>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.uri.0}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.uri.1}"></constructor-arg>
</bean>
</list>
</constructor-arg>
</bean>
</beans>
redis.properties
配置文件
redis.pool.maxTotal=100
redis.pool.maxIdle=10
redis.pool.minIdle=5
redis.pool.lifo=false
redis.pool.maxWait=1000
redis.uri.0=redis://bb:root@127.0.0.1:6379/0
redis.uri.1=redis://a22:root@127.0.0.1:6378/0
uri格式
redis.uri.0=redis://任意:密码@IP:端口/数据库
使用
ServiceImpl
@Service
public class UserServiceImpl implements IUserService{
@Autowired
private IUserDao ud; //注入dao对象
@Autowired
private ShardedJedisPool pool; //注入连接池对象
private String userKey="userinfo_"; //key的前缀(自定义)
@Override
public Sysuser get(Integer uid) {
Sysuser u=null;
ShardedJedis resource=pool.getResource();
String key=userKey+"uid";
//根据key从缓存数据库去数据
String value=resource.get(key);
if(value!=null) { //如果有就返回
u=JSON.parseObject(value,Sysuser.class);
}else { 缓存穿透再去数据库查
u=ud.get(uid);
value=JSON.toJSONString(u);
resource.setex(key,60,value ); //设置超时时间
}
return u;
}
}
handler
@Controller
@RequestMapping("/user2")
public class UserHandler2 {
@Autowired
private IUserService us;
@RequestMapping("/get")
@ResponseBody
public Sysuser get(Integer uid) {
Sysuser u=us.get(uid);
return u;
}
}
访问
控制台
可以看到,连续查询uid为1 的用户数据,程序只向mysql取了一次数据,后面的就是从缓存数据库取出的。
除非超过了设置的超时时间,才会再次向mysql取数据。
本次演示用到的实体类、数据表
public class Sysuser {
private Integer uid;
private String uname;
private String upwd;
//省略setter getter
}