B068-项目实战-技术准备-Nosql-redis

目录

      • 概述
        • Redis简介:
        • NoSql分类:
        • Redis是什么
        • 特点(优势)
        • Mysql、Memcached和Redis的比较
        • 使用场景
      • 应用
        • 安装
        • 使用默认客户端redis-cli/命令行操作
          • 对value为string类型的常用操作
          • 对key的常用操作
          • 对list集合的常用操作
          • 其他命令行操作
        • java客户端操作Redis-jedis
          • 简单操作
          • 使用连接池简单访问Redis
          • 项目中操作redis - 两种方式
            • 工具类方式 JedisUtil
            • Springboot Spring data redis
        • Redis持久化
          • RDB模式
          • AOF追加模式
        • 淘汰策略

概述

Redis简介:

NoSql,key-value,数据在内存中,二进制序列化数据,

NoSql分类:

B068-项目实战-技术准备-Nosql-redis_第1张图片
redis和memcached是key-value的Nosql,主要用来做缓存的。
列存储主要用HBase,用作大数据。

Redis是什么

见文档

特点(优势)

见文档

Mysql、Memcached和Redis的比较

见文档

使用场景

中央缓存:经常要被查询的热点数据,把数据库的热点数据同步到Redis 内存,减轻数据库压力,减少访问时间。

计数器应用:支持自增,注册用户数,浏览次数,转发数、点赞数等等。

实时防攻击系统:暴力破解:使用工具不间断尝试各种密码进行登录。防:ip—>num,到达10次以后自动锁定IP,30分钟后解锁

设定有效期的应用:vip,红包,当session使用,存储登录对象, 设定一个数据,到一定的时间失效。 自动解锁,购物券

自动去重应用:set

构建队列系统:使用 list 可以构建队列系统,使用 sorted set 甚至可以构建有优先级的队列系统。秒杀:可以把名额放到内存队列(redis),内存就能处理高并发访问。

消息订阅系统:Pub/Sub 构建实时消息系统 Redis 的 Pub/Sub 系统可以构建实时的消息系统,比如很多用 Pub/Sub 构建的实时聊天系统的例子,比如QQ群消息。

排行榜:zset有排序功能,可以实现各种排行榜

应用

安装

Redis 的官方下载站是 http://redis.io/download,可以去上面下载最新的安装程序下来。http://redis.cn/

绿色软件,不需要安装,直接解压使用
B068-项目实战-技术准备-Nosql-redis_第2张图片

使用默认客户端redis-cli/命令行操作

带上配置启动redis服务
在redis解压目录cmd,redis-server.exe redis.windows.conf。(带上配置,不然会使用原始默认配置) (然后注意不要关闭服务端)

连接到redis进行操作
方式一:redis-cli -h 127.0.0.1 -p 6379
方式二:D:\soft\Redis-x64-5.0.9>redis-cli.exe
方式三:直接双击redis-cli.exe

对value为string类型的常用操作
127.0.0.1:6379> set name mingfeng		//将字符串值value关联到key
OK
127.0.0.1:6379> get name				//返回key关联的字符串值
"mingfeng"
127.0.0.1:6379> keys *					//获取所有key列表
1) "name"
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> keys *		
1) "age"
2) "name"
127.0.0.1:6379> expire name 10			//设置key的过期时间(xx秒后过期)
(integer) 1
127.0.0.1:6379> ttl name				//查看key的过期时间
(integer) -2
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> clear					//清除记录
127.0.0.1:6379> mset name mf age 31 sex nan		//批量设置一个或多个 key-value 对
OK
127.0.0.1:6379> keys *
1) "sex"
2) "name"
3) "age"
127.0.0.1:6379> mget name age sex				//返回所有(一个或多个)给定 key 的值
1) "mf"
2) "31"
3) "nan"
127.0.0.1:6379> incr age						//将 key 中储存的数字值增1(key不存在,则初始化为0,再加1)
(integer) 32
127.0.0.1:6379> incr age
(integer) 33
127.0.0.1:6379> get age
"33"
127.0.0.1:6379> decr age						//将 key 中储存的数字值减1(key不存在,则初始化为0,再减1)
(integer) 32
127.0.0.1:6379> get age
"32"
127.0.0.1:6379> incrby age 5					//自增多少
(integer) 37
127.0.0.1:6379> decrby age 8
(integer) 29
对key的常用操作
接上
127.0.0.1:6379> del age						//删除key
(integer) 1
127.0.0.1:6379> keys *
1) "sex"
2) "name"
127.0.0.1:6379> expire sex 1
(integer) 1
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1					//换库,有16个库,默认在0号库,0号库无标识,其他库有标识
OK
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> mset name mf sge 20
OK
127.0.0.1:6379[1]> keys *
1) "sge"
2) "name"
127.0.0.1:6379[1]> flushdb					//清空当前库
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> mset name mf age 20
OK
127.0.0.1:6379[1]> keys *
1) "age"
2) "name"
127.0.0.1:6379[1]> flushall					//清空所有库
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty list or set)
对list集合的常用操作
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> lpush stus zs ls			//将一个或多个值 value 插入到列表 key 的表头(最左边)
(integer) 2
127.0.0.1:6379> lrange stus 0 1				//返回列表 key 中指定区间内的元素,0-1
1) "ls"
2) "zs"
127.0.0.1:6379> lrange stus 0 -1			//返回列表 key 中指定区间内的元素,查询所有的stop为-1即可
1) "ls"
2) "zs"
127.0.0.1:6379> lrange stus 1 -1			//返回列表 key 中指定区间内的元素,1-所有
1) "zs"
127.0.0.1:6379> rpush stus ww zl wbd		//将一个或多个值 value 插入到列表 key 的表尾(最右边)
(integer) 5
127.0.0.1:6379> lrange stus 0 -1
1) "ls"
2) "zs"
3) "ww"
4) "zl"
5) "wbd"
127.0.0.1:6379> lpop stus					//移除并返回列表 key 的头(最左边)元素
"ls"
127.0.0.1:6379> lrange stus 0 -1
1) "zs"
2) "ww"
3) "zl"
4) "wbd"
127.0.0.1:6379> rpop stus					//移除并返回列表 key 的尾(最右边)元素
"wbd"
127.0.0.1:6379> lrange stus 0 -1			
1) "zs"
2) "ww"
3) "zl"
127.0.0.1:6379> lpush stus aa bb cc dd ee aa bb ff gg
(integer) 12
127.0.0.1:6379> lrange stus 0 -1
 1) "gg"
 2) "ff"
 3) "bb"
 4) "aa"
 5) "ee"
 6) "dd"
 7) "cc"
 8) "bb"
 9) "aa"
10) "zs"
11) "ww"
12) "zl"
127.0.0.1:6379> lrem stus 2 aa			//根据count值移除列表key中与参数 value 相等的元素
(integer) 2								//count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素
127.0.0.1:6379> lrange stus 0 -1
 1) "gg"
 2) "ff"
 3) "bb"
 4) "ee"
 5) "dd"
 6) "cc"
 7) "bb"
 8) "zs"
 9) "ww"
10) "zl"
127.0.0.1:6379> lrem stus -1 bb			//count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素
(integer) 1
127.0.0.1:6379> lrange stus 0 -1
1) "gg"
2) "ff"
3) "bb"
4) "ee"
5) "dd"
6) "cc"
7) "zs"
8) "ww"
9) "zl"

通过lpush和rpop,或rpush和lpop可实现队列
通过lpush和lpop,或rpush和rpop可实现栈

其他命令行操作

可见chm文档

java客户端操作Redis-jedis

java客户端包括:Redisson,aredis,JDBC-Redis,Jedis,JRedis,等

1.创建普通java项目
2.创建lib包, 导两个jar包, add as library
3.写代码测试

简单操作
public class JedisTestString {

    @Test
    public void test(){
        //获取链接
        Jedis jedis = new Jedis("127.0.0.1",6379,2*1000);
        //简单操作
        jedis.set("name","mf");
        System.out.println(jedis.get("name"));
        //关闭连接
        jedis.close();
    }
}
使用连接池简单访问Redis
public class JedisTestPoolSpring {

    @Test
    public void test(){
        //连接池配置
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(2);               //最小连接
        config.setMaxTotal(8);              //最大连接
        config.setMaxWaitMillis(2*1000);    //连接超时时间
        config.setTestOnBorrow(true);       //在获取之前校验连接是否可用
        //1 创建连接池
        //2 配置连接池的参数
        JedisPool pool = new JedisPool(config,"127.0.0.1",6379,2*1000);
        //3 通过连接池获取连接
        Jedis jedis = pool.getResource();
        //4 操作
        jedis.set("name","mingfeng");
        System.out.println(jedis.get("name"));
        //5 释放连接
        jedis.close();
        //6 销毁连接池
        pool.destroy();
    }
}
项目中操作redis - 两种方式
工具类方式 JedisUtil

要自己写,不推荐

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
 * 整个单例: 枚举限制实例只有一个就是单例
 */
public enum  JedisUtil {
    INSTANCE;
    private 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 通过配置对象创建连接池对象 //正常来说应该配置到properties
        pool = new JedisPool(config,"127.0.0.1",6379,2*1000);
    }   //没加密码参数

    //4 获取连接
    /*public Jedis getResource(){
        return pool.getResource();
    }*/
    public Jedis getCollection(){
        if(pool!=null){
            return pool.getResource();
        }
        return null;
    }


    //6 释放连接
    public void release(Jedis jedis){
        if (jedis != null) {
            jedis.close();
        }
    }


    //常用操作封装到里面
    //设置字符串
    public void set(String key,String val){
        Jedis jedis = null;
        try {
            jedis = this.getCollection();
            jedis.set(key,val);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            this.release(jedis);
        }
    }
    //获取字符串
    public String get(String key){
        Jedis jedis = null;
        try {
            jedis = this.getCollection();
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            this.release(jedis);
        }
        return null;
    }
    //设置带添加超时时间的字符串
    public void set(String key,String val,int seconds){
        Jedis jedis = null;
        try {
            jedis = this.getCollection();
            //设置值时设置超时时间
            jedis.setex(key,seconds,val);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            this.release(jedis);
        }
    }
}
public class JedisTestJedisUtil {

    public static void main(String[] args) {
        Jedis jedis = JedisUtil.INSTANCE.getCollection();
        jedis.set("name","lisisi" );
        System.out.println(jedis.get("name"));
    }
}
Springboot Spring data redis

Spring data:spring对数据操作的支持规范,我们的数据是多种类型,rdbms(msyql),redis(Nosql),es,mq
Spring data redis :spring操作redis
Spring data jpa :操作关系型数据库
。。。
Springboot Spring data redis:简化spirngdata对redis的配置
B068-项目实战-技术准备-Nosql-redis_第3张图片
1.搭建spirngboot项目
A 创建maven项目
B 导包 parent web test
C 启动类
2.使用springdataredis
A 导包
B 配置属性
C 编写测试类 (基于springboot的测试类)
D 使用springdataredis 提供的工具类 直接操作redis


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>
# redis 属性信息
## redis数据库索引(默认为0)
spring.redis.database=0
## redis服务器地址
spring.redis.host=localhost
## redis服务器连接端口
spring.redis.port=6379
## redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
## 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=2
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
## 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class SpringDataTest {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;    //可以存对象,对象要实现序列化才能向redis存储

    @Test
    public void testString(){
        stringRedisTemplate.opsForValue().set("name", "mingfeng");
        System.out.println(stringRedisTemplate.opsForValue().get("name"));
    }

    @Test
    public void testObject(){
        redisTemplate.opsForValue().set("laozhu",new User(1L,"老朱"));
        System.out.println(redisTemplate.opsForValue().get("laozhu"));
    }
}

Redis持久化

从内存到磁盘,通过配置实现

配置文件redis.windows.conf:

bind 127.0.0.1			指定那些ip可以访问我
port 6379				默认端口,可以改
timeout 0				超时时间,0:默认永不超时
loglevel notice			日志级别,notice相当于info
logfile ""				日志输出位置,如:logfile "./redis.log"

save 900 1				redis持久化的第一个策略,rdb策略,将数据存储到磁盘并生成.rdb后缀的文件
save 300 10
save 60 10000			如果一分钟写了10000次就往rdb文件写一次,写数据并打乱进行编码

appendonly no			生成.aof文件,写一次追加一把,时间不满足rdb的范围就往.aof写,满足后从.aof刷到.adb
						掉电重启后会先校验appendonly是否为yes,如果是会拿到.aof里面内容解析,再加上rdb里面内容放到内存
RDB模式

RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照,默认开启该模式.
如何关闭 rdb 模式:save “”

# save 900 1        //至少在900秒的时间段内至少有一次改变存储同步一次
# save xxx
# save 60 10000
AOF追加模式

AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,默认关闭该模式。
如何开启aof模式:

appendonly yes

小结:
redis是怎么保存数据?
redis为了考虑效率,保存数据在内存中.并且考虑数据安全性,还做数据持久化,如果满足保存策略,就会把内存的数据保存到数据rdb文件,还来不及保存那部分数据存放到aof更新日志中。在加载时,把两个数据做一个并集。

淘汰策略

淘汰一些数据,达到redis数据都是有效的,节约内存资源。选择合适的淘汰策略进行淘汰。

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
allkeys-lru:从所有数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

maxmemory 					//自己设置大小
maxmemory-policy volatile-lru		//配置淘汰策略

你可能感兴趣的:(笔记总结,nosql,redis,数据库)