【Redis】redis入门保姆教程

数据库分类

  1. 关系数据库(Sql):mysql,sqlserver;存放在硬盘中,查询的的时候是通过io操作。
  2. 非关系数据库(NoSql):Redis(持久化机制。淘汰策略),数据存放在内存中,因此也叫内存数据库。
  3. jvm内置缓存框架:EH cache 、OS cache

Sql与NoSql

sql:关系型数据库 NoSql:非关系型数据库

  1. 结构化:所有的字段与值之间具有强烈的约束关系,比如n个值只能对应一个表头的key 而NoSql是非结构化:拿Redis举例子,数据以key-value的形式保存,并且key可以封装成json对象,此外每一条json对象之间的key允许重复,因此没有强烈的约束关系。
  2. 关联:关系型数据库表与表之间可以通过外键进行关联,而Nosql的数据存储是通过json对象嵌套实现的,数据库本身不会去关联某个json对象,需要程序员自己去实现关联。

在这里插入图片描述

Redis特性:

在这里插入图片描述

Redis持久化机制好在哪里?

Redis可以把数据持久化,缓存到硬盘里,这样假如Redis宕机了,只需要重启Redis,可以从硬盘中恢复数据。

Redis的特性:分布式共享

在这里插入图片描述
在以前的老项目中使用到的jvm内置缓存框架,假如有多个服务器做集群的情况下,每一个jvm缓存,都会缓存一份,有一个缓存数据进行修改了,那么其他的缓存的数据也要跟着修改。而Redis的分布式管理,所有的服务器的数据都会放入Redis,保证了两台服务器的同步性。所以这也是为什么Redis支持分布式共享。

Redis的应用场景

  1. Token令牌的生成
  2. 短信验证码的code作为key存入Redis
  3. 实现缓存查询数据,减轻数据库访问压力(数据库底层是io操作,频繁访问数据库,执行效率性能低)
  4. Redis实现计数器(Redis支持单线程,保证了原子性)
  5. 分布式锁
  6. 延迟操作(例如电商平台下单不支付的情况下,生成token令牌,设置有效期为多少,超过了有效期,则进行订单的销毁操作)
  7. 分布式消息中间件

Redis环境搭建

1.创建虚拟机

安装linux环境:: 安装Linux教程
随后打开vm ware,你已经启动了一台Linux下的虚拟机
在这里插入图片描述

2.连接虚拟机

然后打开MobaXterm连接这台虚拟机,连接成功后:
在这里插入图片描述

3.安装Redis环境:

 yum install -y gcc tcl

安装完毕后,将下载好的redis安装包拖拽到/usr/local/src目录下:
在这里插入图片描述

3.解压redis安装包

 tar -zxvf redis-7.0.5.tar.gz

在这里插入图片描述
解压完后进入到安装包

 cd redis-7.0.5/

4.启动安装包

make && make install

当你看到这三个文件,说明安装成功了
在这里插入图片描述
在这里插入图片描述

redis-cli:是redis提供的命令行客户端

redis-server:是redis的服务端启动脚本

redis-sentinel:是redis的哨兵启动脚本

Redis启动

1.前台启动Redis(在任意目录下)

redis-server

那么前台启动完成了不过你不可以做任何操作。因此我们生产环境一般都是后台启动的!

2.后台启动Redis:需要修改配置文件

1.首先进入到安装目录

 cd /usr/local/src/redis-7.0.5/

2.备份配置文件

cp redis.conf redis.conf.bck

3.修改配置文件

vi redis.conf

在这里插入图片描述
在这里插入图片描述
这里我们把redis服务器密码设置成了123321,这个记住,后面要用到!

在这里插入图片描述

接下来就可以进行后台启动了:

4.后台启动配置文件

redis-server redis.conf

此时已经运行完配置文件,但是并没有真正的启动Redis!!想要查看是否运行成功可以使用:

ps -ef | grep redis

在这里插入图片描述
当看到redis-server就说明redis-server被加载了,但是还未启动!

5.杀死后台进程

使用kill命令杀死后台进程

kill -9 7668

3.Reids开机自启

1.修改配置文件

vi /etc/systemd/system/redis.service

修改为

[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-7.0.5/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

2.接下来重载服务

systemctl daemon-reload

3.此时你就可以使用systemctl命令:

#启动redis
systemctl start redis

#停止redis
systemctl stop redis

#重启redis
systemctl restart redis

# 查看redis状态
systemctl status redis

#开机自启redis
systemctl enable redis

*不同动作下的Redis status:

  1. start :starting->started准备启动,启动完毕
    在这里插入图片描述
  2. Restart stopped->starting->started 停止完毕,准备启动,启动完毕
    在这里插入图片描述
  3. stop(stopping->stopped 准备停止,停止完毕)会把所有的日志全部输出
    在这里插入图片描述

Redis客户端

1.命令行客户端

1.进入到bin目录

cd /usr/local/bin/

2.使用命令行客户端redis-cli [option] [command]

redis-cli -h 192.168.239.128 -p 6379

3.使用AUTH设置密码,与-a选项等价

#这里的密码与redis.conf文件里的requirepass 密码对应
AUTH 123321

示范:
在这里插入图片描述

2.桌面客户端

下载地址 RedisDesktopManager
在这里插入图片描述
下载好了之后,连接虚拟机的IP,密码是redis服务器的密码。(与前面设置的redis.conf文件里的requirepass 密码对应:123321)
在这里插入图片描述
在这里插入图片描述

随后就能看到16个redis的库。这些库的名称不能修改。

在这里插入图片描述

3.连接失败解决方案

ps:如果连不上,说明Redis服务未开启,可以使用systemctl命令启动服务:

systemctl start redis

如果还是连不上,就关闭linux下的防火墙:

systemctl stop firewalld.service

Redis的数据结构

在这里插入图片描述
String:将对象序列化为json字符串后存储,值是字符串。
Hash:值是哈希表,也称散列表。
List:值是list集合,与java中的LinkedList相似,是一个双向链表结构,可正向检索也可反向检索,List是有序的。
Set:Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征。

Redis常用命令

通用命令

  1. KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
  2. DEL:删除一个指定的key
  3. EXISTS:判断key是否存在
  4. EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
  5. TTL:查看一个KEY的剩余有效期

TTL的值为-1时代表永久有效,-2代表过期。

String类型的命令

  1. SET:添加或者修改已经存在的一个String类型的键值对
  2. GET:根据key获取String类型的value
  3. MSET:批量添加多个String类型的键值对
  4. MGET:根据多个key获取多个String类型的value
  5. INCR:让一个整型的key自增1
  6. INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2让num值自增2
  7. INCRBYFLOAT:让一个浮点类型的数字自增并指定步长
  8. SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
  9. SETEX:添加一个String类型的键值对,并且指定有效期

Redis的Key格式

redis的key是主键且唯一的,为了区分不同类型下的同名key,redis推出了层级存储key的方式:

set ProjectName:product:1 '{"id":1,"name":"RedmiK50 Pro","price":"9999"}'

Hash

在这里插入图片描述

  1. HSET key field value:添加或者修改hash类型key的field的值
  2. HGET key field:获取一个hash类型key的field的值
  3. HGETALL:获取一个hash类型的key中的所有的field和value
  4. HKEYS:获取一个hash类型的key中的所有的field
  5. HVALS:获取一个hash类型的key中的所有的value
  6. HINCRBY:让一个hash类型key的字段值自增并指定步长
  7. HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

List

  1. LPUSH key element …:向列表左侧插入一个或多个元素
  2. LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
  3. RPUSH key element …:向列表右侧插入一个或多个元素
  4. RPOP key:移除并返回列表右侧的第一个元素
  5. LRANGE key star end:返回一段角标范围内的所有元素
  6. BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

Set

  1. SADD key member …: 向set中添加一个或多个元素
  2. SREM key member …:移除set中的指定元素
  3. SCARD key:返回set中元素的个数
  4. SISMEMBER key member:判断一个元素是否存在于set中
  5. SMEMBERS:获取set中的所有元素
  6. SINTER key1 key2 …:求key1与key2的交集
  7. SDIFF key1 key2 …:求key1与key2的差集
  8. SUNION key1 key2 …:求key1和key2的并集

SortedSet

Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。
SortedSet具备下列特性:
可排序。 元素不重复查询速度快。因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。

  1. ZADD key score member:添加一个或多个元素到sorted set,如果已经存在则更新其score值
  2. ZREM key member:删除sorted set中的一个指定元素
  3. ZSCORE key member:获取sorted set中的指定元素的score值
  4. ZRANK key member:获取sorted set中的指定元素的排名ZCARD key:获取sorted set中的元素个数
  5. ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
  6. ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
  7. ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
  8. ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
  9. ZDIFF、ZINTER、ZUNION:求差集、交集、并集

所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可

Jedis

jedis是服务于Redis的java客户端
使用jedis需要的步骤如下:

1.引入依赖

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.3.0</version>
        </dependency>

2.建立连接(ip、端口号、密码认证)、释放资源

@SpringBootTest
class JedisApplicationTests {
    private Jedis jedis;
    @BeforeEach
    void setup() {
        //建立连接
        jedis = new Jedis("192.168.239.128", 6379);
        //设置密码
        jedis.auth("123321");
        jedis.select(1);
    }
    @AfterEach
    void close(){
        if (jedis!=null){
            jedis.close();
        }
    }
}

3.测试:jedis拥有的方法与redis的命令一致

@Test
    void test(){
        String rs = jedis.set("name", "kxy");
        System.out.println(rs);
        String s = jedis.get("name");
        System.out.println(s);
    }

Jedis连接池

由于jedis是线程不安全的,频繁销毁和创建jedis对象会造成性能损耗,因此使用jedis连接池来代替jedis:

public class JedisConnectFactory {
    private static final JedisPool jedisPool;

    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);
        poolConfig.setMaxIdle(8);
        poolConfig.setMaxIdle(0);
        jedisPool = new JedisPool(poolConfig, "192.168.239.128", 6379, 1000, "123321");
    }
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

那么配置好了连接池,就可以从连接池中获取jedis对象了:

 void setup() {
        //建立连接
        jedis = JedisConnectFactory.getJedis();
        //设置密码
        jedis.auth("123321");
        jedis.select(1);
    }

SpringDataRedis

RedisTemplate

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:
在这里插入图片描述

使用springboot内置的SpringDataRedis

1. 导入springboot内置redis依赖和连接池

	   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

2. 配置文件

spring:
  redis:
    host: 192.168.239.128
    port: 6379
    password: 123321
    lettuce:
      pool:
        max-active: 8 # 最大连接
        max-idle: 8 # 最大空闲连接
        min-idle: 0 #
        max-wait: 100 # 等待连接时间

3.测试

@SpringBootTest
class RedisApplicationTests {
    @Resource
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("name","lisi");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }
}

由于RedisTemplate 默认的序列化方式是jdk 序列化,这样就会导致我们存储key或value的最终显示在客户端上会出现地址,这是我们不期望的。
在这里插入图片描述
在这里插入图片描述

因此我们需要写一个配置类去修改redisTemplate的序列化方式:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //创建RedisTemplate对象
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setHashKeySerializer(serializer);
        // 设置Value的序列化
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);
        //返回
        return redisTemplate;
    }
}

通用版:

@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}

StringRedisTemplate

由于Json的序列化方式,在反序列化的的前提是确定class类型,因此会把class字节码对象存入到Json对象中,而class字节码对象会带来额外的内存开销。
为了解决这个问题,我们通常不会用json的序列化器,而是使用String序列化器:只能存储String类型的key和value。当存储的是一个java对象时,则需要程序员手动的完成对象的序列化和反序列化。
而正好spring提供了一个StringRedisTemplate类,它的序列化方式默认就是String方式。

以下是分别是存储普通的字符串的key和value以及一个java对象序列化成json对象存储到redis的示例

@SpringBootTest
class RedisStringTests {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Test
    void testString() {
        //写入数据存入redis
        redisTemplate.opsForValue().set("name1","zs1");
        //取数据
        Object name1 = redisTemplate.opsForValue().get("name1");
        System.out.println(name1);
    }
    private static final ObjectMapper mapper = new ObjectMapper();
    @Test
    void testSaveUser() throws JsonProcessingException {
        User user = new User("zhangsan", 21);
        //手动序列化:将java对象转成json字符串
        String json = mapper.writeValueAsString(user);
        //数据存入redis
        redisTemplate.opsForValue().set("user:200",json);
        //获取数据
        String jsonUser = redisTemplate.opsForValue().get("user:200");
        //手动反序列化:
        User user1 = mapper.readValue(jsonUser, User.class);//参数1:要反序列化的json对象。参数2:要反序列化成的类型
        System.out.println("user1="+user1);
    }

}

总结:redisTemplate的序列化两种方式

  1. 在RedisConfig配置类自定义redisTemplate方法,在此方法内修改RedisTemplate的默认序列化器为只保存String类型的key,value的序列化器,比如jackson2序列化器,fastJson序列化器等等。
  2. 使用spring提供的StringRedisTemplate,写入redis的时候手动的把java对象序列化为json对象,读取redis的数据时手动的把json对象反序列化为Java对象。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

❀༊烟花易冷ღ࿐❀

觉得博客写的不错就打赏一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值