Redis概述:
1.nosql:泛指非关系型数据库(不以关系来建模的数据库)【由行和列组成的二维表的数据库就是关系型数据库】
2.键值(key-value):主要用于内容缓存,优点查找速度快
Redis是一个key-value的nosql,主要用来做缓存!
3.Redis数据保存在内存中,存取速度快,并发能力强。
4.是一种数据结构化存储方法的集合。数据结构:数组,list,map,tree等;
Redis提供了一堆方法,调用特定的方法把数据保存为特定的数据结构。
5.Redis官方不支持windows,有团队制作了windows版本的。
特点(优势):
数据存储:
存放到内存中,并且还能不定期持久化到硬盘.
Value类型:
相较于memcached支持Value更多
客户端支持:
支持多种客户端-跨语言
超大并发支持:
支持集群
存储过期:存储数据时设置一个有效期,时间到了就没了.
场景:订单,vip,短信验证码,游戏道具,优惠券,红包等等
面试题:Memcached和Redis的相同点和不同点? 用过Memcached吗?
用过redis,
相同点:
都是key-value类型Nosql,都存放数据到内存中,读写效率高,而且都支持存储过期.
不同点:
redis相较于Memcached还支持持久化到磁盘,数据安全更高.
redis相较于Memcached支持value类型更多.
使用redis
1.选择合适的java客户端(jedis)
2.使用java客户端操作redis服务器
①连接
②连接池
使用连接池的作用?
1.限定了最大连接数,防止连接过多大值系统崩溃
2.不用重复创建和关闭连接,这两个都是耗资源操作,节约了资源
3.不用重复创建和关闭连接,这两个都是耗时操作,减少访问时间,增强用户体验
连接池配置:
最小连接数
config.setMaxIdle(2);//最小连接(闲时最大连接)
最大连接数
config.setMaxTotal(10);//最大连接
最大超时时间
config.setMaxWaitMillis(2*1000);//最大等
测试连接是否畅通
config.setTestOnBorrow(true);//获取连接时测试是否畅通
注:配置文件:bind ip 绑定ip,只能这个ip来访问,保证安全
默认不会丢失数据appendonly yse
appendonly 改为no后会丢失数据
修改save满足改为no之后也不会丢失数据
redis持久化策略
面试题:
淘汰策略:放开配置的最大内存(maxmemory ),
放开选择的淘汰策略(allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰)。
复习事务四大特征:(面试题!!!) redis有事务,但是没有用
原子性:多个操作要么都成功,要么都失败!
一致性:多个操作,如果后面的失败了,前面要进行回滚达到数据一致.
隔离型:多个事务相互不影响
持续性:一旦开始就不能终止
JedisUtil
public enum JedisUtil {
INSTANCE;
public static JedisPool pool=null;
//连接池单例
static {
//1.创建连接池配置对象
JedisPoolConfig config = new JedisPoolConfig();
//2.进行配置-四个
config.setMaxIdle(2);//最小连接(闲时最大连接)
config.setMaxTotal(10);//最大连接
config.setMaxWaitMillis(2*1000);//最大等待时间
config.setTestOnBorrow(true);//获取连接时测试是否畅通
//3.通过配置对象创建连接池
pool = new JedisPool(config, "127.0.0.1", 6379, 2*1000,"root");
}
//获取连接
public Jedis getResource(){
return pool.getResource();
}
//释放链接
public void closeJedis(Jedis jedis){
if (jedis!=null){
jedis.close();
}
}
}
RedisClientJedisTest
public class RedisClientJedisTest {
@Test
public void testSet()throws Exception{
//创建连接
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.auth("root");
//执行操作
jedis.set("name","ls");
//关闭连接
jedis.close();
}
@Test
public void testGet()throws Exception{
//创建连接
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.auth("root");
//执行操作
System.out.println(jedis.get("name"));
//关闭连接
jedis.close();
}
/**
* 连接池-设置并获取值
* @throws Exception
*/
@Test
public void testPool()throws Exception{
//如果创建一个对象后要做很多配置,不如先创建他的配置对象后,再通过配置对象创建它。
//1.创建连接池配置对象
JedisPoolConfig config = new JedisPoolConfig();
//2.进行配置-四个
config.setMaxIdle(2);//最小连接(闲时最大连接)
config.setMaxTotal(10);//最大连接
config.setMaxWaitMillis(2*1000);//最大等待时间
config.setTestOnBorrow(true);//获取连接时测试是否畅通
//3.通过配置对象创建连接池
JedisPool pool = new JedisPool(config, "127.0.0.1", 6379, 2 * 1000,"root");
//4.通过连接池获取连接
Jedis connection = pool.getResource();
//5.执行操作-设置和获取值
connection.set("name","zs");
System.out.println(connection.get("name"));
//6.释放链接
connection.close();
//7.摧毁连接(测试环境)真实环境应该是在spring中配置的一个单例
pool.destroy();
}
}
RedisClientJedisOprsTest
public class RedisClientJedisOprsTest {
@Test
public void testKey()throws Exception{
//清空所有数据-flushall
//获取连接
Jedis jedis = JedisUtil.INSTANCE.getResource();
System.out.println("清空数据:"+jedis.flushAll());
System.out.println("判断key为age的值是否存在:"+jedis.exists("age"));
System.out.println("设置key为age的值"+jedis.set("age", "18"));
System.out.println("设置key为age的值"+jedis.set("name", "zl"));
System.out.println("设置key为age的值"+jedis.set("sex", "nan"));
System.out.println("设置key为age的值"+jedis.set("num", "001"));
System.out.println("再次判断key为age的值是否存在:"+jedis.exists("age"));
System.out.println("设置后获取key为age的值"+jedis.get("age"));
System.out.println("删除前判断key为age的值是否存在:"+jedis.exists("age"));
System.out.println("删除key为age的值"+jedis.del("age"));
System.out.println("删除后判断key为age的值是否存在:"+jedis.exists("age"));
System.out.println("获取所有的key:");
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println(key+"--->"+jedis.get(key));
}
jedis.expire("name",20);
Thread.sleep(5000);
System.out.println("过期剩余时间:"+jedis.ttl("name"));
//释放资源
JedisUtil.INSTANCE.closeJedis(jedis);
System.out.println("释放连接");
}
@Test
public void testString()throws Exception{
//清空所有数据-flushall
//获取连接
Jedis jedis = JedisUtil.INSTANCE.getResource();
System.out.println("清空数据:"+jedis.flushAll());
System.out.println("add...");
jedis.set("name","ly");
System.out.println(jedis.get("name"));
System.out.println("updtate...");
jedis.set("name","lsj");
System.out.println(jedis.get("name"));
jedis.set("age","30");
System.out.println("append...");
jedis.append("name","=ly");
System.out.println(jedis.get("name"));
System.out.println(jedis.get("age"));
System.out.println("del...");
jedis.del("age");
System.out.println("get...");
System.out.println(jedis.get("name"));
System.out.println(jedis.get("age"));
//释放资源
JedisUtil.INSTANCE.closeJedis(jedis);
System.out.println("释放连接");
}
@Test
public void testString2()throws Exception{
//清空所有数据-flushall
//获取连接
Jedis jedis = JedisUtil.INSTANCE.getResource();
System.out.println("清空数据:"+jedis.flushAll());
jedis.mset("name","ww","age","50","sex","男");
List<String> list = jedis.mget("name","age","sex");
for (String s : list) {
System.out.println(s);
}
//释放资源
JedisUtil.INSTANCE.closeJedis(jedis);
System.out.println("释放连接");
}
@Test
public void testString3()throws Exception{
//清空所有数据-flushall
//获取连接
Jedis jedis = JedisUtil.INSTANCE.getResource();
System.out.println("清空数据:"+jedis.flushAll());
jedis.setex("name",20,"lsj");
jedis.set("age","20");
System.out.println("自增前"+jedis.get("age"));
jedis.incr("age");
System.out.println("自增1后前"+jedis.get("age"));
jedis.decr("age");
System.out.println("自减1后前"+jedis.get("age"));
//jedis.incrBy(, )
jedis.incrBy("age",10);
System.out.println("自增10后前"+jedis.get("age"));
jedis.decrBy("age",10);
System.out.println("自减10后前"+jedis.get("age"));
//释放资源
JedisUtil.INSTANCE.closeJedis(jedis);
System.out.println("释放连接");
}
}