Radis—非关系型数据库

一、NOSQL和RDBMS

NOSQL(Not only sql,对非关系型数据库的统称):redis
RDBMS(关系数据库管理系统):mysql

区别:

RDBMS

  • 高度组织化结构化数据。 user—userid username age sex …
  • 结构化查询语言(SQL) sql语句
  • 数据和关系都存储在单独的表中。
  • 数据操纵语言DML,数据定义语言DDL
  • 严格的一致性. 事务
  • 基于事务

NoSQL

  • 代表着不仅仅是SQL
  • 没有声明性查询语言
  • 键 - 值对存储。
  • 最终一致性,而非ACID【原子,一致,隔离,持久】属性
  • 非结构化和不可预知的数据 字符串 对象 队列 集合
  • 高性能,高可用性和可伸缩性。 适合搭建集群。 mysql搭建集群。非常复杂。主从模式

二、redis

Redis是一种开放源代码(BSD许可)的内存中数据结构存储,用作数据库,缓存和消息代理。Redis提供数据结构,例如字符串,哈希,列表,集合,带范围查询的排序集合,位图,超日志,地理空间索引和流。Redis具有内置的复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster自动分区提供了高可用性。

三、redis安装:可以使用xshall来查看和更改文件

redis没有windows版本,只能在linux上面使用
1、准备redis运行环境,需要c++:yum install -y gcc-c++
2、下载redis安装包,复制到安装目录并解压
3、进入解压后的redis目录,执行编辑命令: make
4、执行安装命令:make install
5、开启redis服务: redis-server redis.conf

开启服务之后,如果出现如下界面,说明redis运行成功
在这里插入图片描述接下来使用redis客户端连接redis服务器
redis-cli -h redis服务器的ip(默认,可更改) -p redis服务器的(默认,可更改)端口号
redis-cli -h 127.0.0.1 -h 6379
redis配置文件中必须要知道的内容
在这里插入图片描述在这里插入图片描述在这里插入图片描述

redis图形化界面的客户端(建议使用,方便查看,但是增删改功能······有限)
在这里插入图片描述

四、redis常用命令

在使用redis客户端连接redis服务器后,才可以使用以下命令
在这里插入图片描述
redis支持的数据类型

1. String字符串类型
2. Hash 哈希类型
3. list 队列
4. set 集合
5. sorted set 有序集合。
  1. String字符串类型

set key value: 把字符串的value存放到对应的key上。
get key: 根据指定的key获取对应字符串的value
mset key value key value key value…: 一次存放多个字符串的value到相应的key上
mget key key…: 根据指定的多个key获取对应的字符串的value
setnx key value:把指定的value存放到对应的key上,如果对应的key已经存在,则不存储。 如果不存在则存储。 返回0或者1
incr key:为指定的key的value值进行递增。应用场景:点赞 收餐 转发等
decr key: 递减

  1. Hash 类型

hset key field value: 存放一个指定key的field-value的数据库 hget key
field:获取指定key的field字段对应的value值。 hkeys key: 获取指定key的所有field字段名 hvals
key: 获取指定key的所有value值。 hgetall key: 获取指定key的所有的field和value值。 HDEL key
field: 删除指定key的field字段。

3.List 队列类型

lpush: 将一个或多个值 value 插入到列表 key 的表头.
lpop: 移除并返回列表 key 的头元素。
lrange:返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

4.set集合

sadd key value…: 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
spop key: 移除并返回集合中的一个随机元素。
smove source destint member:
smembers key:获取指定key下的所有的元素
sinter key key …:求所有集合的交集。

5.sortSet 有序集合。

zadd key score value score value …:添加有序集合元素。
zrange key start end: 获取指定返回的元素。

五、redis的持久化方式

持久化:把内存中的数据库保存到磁盘上。防止数据的丢失。
redis支持的持久化方式两种:
  (1)RDB:*快照*  其实就是把数据以快照的形式保存在磁盘上,什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。
 (2)AOF:*日志追加* 记录服务器接受的每个写入操作,当服务器启动时再次加载该日志,会把日志中的命令重新执行一遍。

1、RDB持久化

(1)手动save命令
(2)手动bgsave命令
(3)通过过配置自动触发

2、save和bgsave的区别

save命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成。
在这里插入图片描述
因为项目访问往往都是高访问,几万到几百万的访问会瞬间阻塞Redis, 很显然,这种方式明显不可取。
执行bgsave命令时,Redis会在后台异步进行快照操作,快照的同时还能响应客户端请求。
在这里插入图片描述

持久化后的文件位置:
在这里插入图片描述进入vi redis.conf,如下图,就是RDB持久化后的的文件名设置
在这里插入图片描述在这里把文件名改一下,方便之后分辨持久化文件(6379:redis的默认端口号)
在这里插入图片描述1.save命令持久化
在这里插入图片描述2.bgsave命令持久化
在这里插入图片描述当然,在这里体会不出两种持久化在性能上的区别,仅作演示两种持久化命令。
bgsave除了这种命令式的持久化,还有可以设置条件来持久化
在这里插入图片描述在这里插入图片描述## 3.RDB的优缺点
优点:

(1)RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
(2)生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
(3)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

缺点:

快照持久化期间修改的数据不会被保存,可能丢失数据。数据完整性比较差。

3.AOF持久化:默认关闭

提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。
在这里插入图片描述依旧是redis.conf文件
在这里插入图片描述在这里插入图片描述在这里插入图片描述

六、Redis集群搭建

1、主从关系:一个主节点,多个从节点

准备工作:

1、创建目录master-slave
2、把redis.conf复制到新建目录中,然后改名 redis1001.conf redis1002.conf redis1003.conf(改成什么无所谓,主要是为了方便区别文件)
3、分别修改三个文件端口号以及rdb持久化文件的名称aof关闭
在这里插入图片描述在这里插入图片描述在这里插入图片描述
4、 启动以上三个文件
在这里插入图片描述
reids5.0版和6.0版本有些区别,比如启动配置文件,5.0每启动一个文件都会弹出三行代码,6.0不会,并不是没有启动成功。
在这里插入图片描述把1002和1003挂载到1001上面之后
挂载代码 slaveof 192.168.137.159 1002
查看节点信息,在ip下输入 info replication
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210423194706717.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pfWVVCTw==,size_16,color_FFFFFF,t_70#pic_center
在这里插入图片描述在这里插入图片描述
在主节点上面可以set、get,但是在从节点上面只能get,不能set

但是,如果主节点挂掉,那么整个集群就失效了
在这里插入图片描述

2、哨兵模式

哨兵模式就是在主节点挂掉的情况下,从节点中会有一个随机成为主节点,这样就可以继续redis服务

  1. 修改sentinel.conf配置 sentinel monitor mymaster 127.0.0.1 7001 1

127.0.0.1 表示redis主节点的ip,在这里要改为虚拟机静态ip
6379 表示主节点的端口号,这里改为主节点ip
2 表示有多少个哨兵选取redis从节点后,该从节点可以当选为主节点。
在这里插入图片描述
启动哨兵:redis-sentinel sentinel.conf
在这里插入图片描述哨兵的缺点:

  1. 没有解决单节点的问题。
  2. 持久化文件始终在一个服务器上。

3、去中心化集群:多主多从

准备工作

1、创建文件夹(tmts),把redis配置文件拉到里面,因为要做三主三从六个redis,先改一个redis配置,剩下的复制粘贴更改里面的端口号就行了。
2、依旧是改配置

port 8001 (区别之前的主从集群和哨兵集群)
bind * -:😗 (redis6.0版是这个,5.0是0.0.0.0) 
daemonize yes
appendonly yes
开启集群 cluster-enabled yes 833行
集群的配置文件,该文件自动生成 cluster-config-file nodes-8001.conf 841行
集群的超时时间 cluster-node-timeout 5000 847行

在这里插入图片描述启动所有的redis:redis-server redis8001.conf ······
在这里插入图片描述为主节点分配槽以及分配从节点

redis-cli --cluster create --cluster-replicas 1 192.168.137.159:8001 192.168.137.159:8002 192.168.137.159:8003 192.168.137.159:8004 192.168.137.159:8005 192.168.137.159:8006

七、redis与java的连接

1、java与redis连接

创建maven项目,导入依赖

		<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.3.0</version>
        </dependency>
public class JedisTest {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.137.159", 6379);//必须运行远程连接 必须防火墙放行该端口号
        //新建字符串
        jedis.set("k1","v1");
        jedis.set("k2","v2");
        jedis.mset("k3","v3","k4","v4");

        //操作key
        Set<String> keys = jedis.keys("*");
        System.out.println("所有keys"+keys);
        jedis.del("k1");
        jedis.close;
    }
}

使用jedis连接池

public class TestPoolJedis {
    public static void main(String[] args) {
        //连接池的配置
        JedisPoolConfig config=new JedisPoolConfig();
        config.setMaxTotal(100);//设置连接池的最大连接数
        config.setMaxIdle(10);//设置最大空闲的个数
        config.setTestOnBorrow(true);//在从连接池这种获取连接对象前是否测试该对象可以。

        //创建连接池对象
        JedisPool jedisPool=new JedisPool(config,"192.168.137.159",6379);

        //获取jedis对象
        Jedis jedis = jedisPool.getResource();
        System.out.println(jedis.get("k3"));

        jedis.close();
    }
}

2、springboot整合redis

springboot为操作redis准备了两个工具类:StringRedisTemplate、RedisTemplate。
StringRedisTemplate是RedisTemplate的子类。StringRedisTemplate的泛型key和value都是String类型。
RedisTemplate的key value的泛型是Object。

引入依赖:

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

配置文件

spring.redis.host=192.168.137.159
spring.redis.port=6379
spring.redis.jedis.pool.max-active=20
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-wait=20000

测试代码:

@SpringBootTest
class SpringbootRedis01ApplicationTests {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Test
    void contextLoads() {
        //操作key
        Set<String> keys = redisTemplate.keys("*");
        System.out.println(keys);
        System.out.println(redisTemplate.getExpire("k3"));

        redisTemplate.expire("k3", 60, TimeUnit.SECONDS);

        System.out.println(redisTemplate.getExpire("k3"));

    }

    @Test
    public void testString(){
        ValueOperations<String, String> forValue = redisTemplate.opsForValue();//操作字符串类型
        forValue.set("k1","v1");
        System.out.println(forValue.get("k1"));

        Map<String,String> map=new HashMap<>();
        map.put("k9","v9");
        map.put("k10","v10");
        forValue.multiSet(map);

        List<String> keys=new ArrayList<>();
        keys.add("k1");
        keys.add("k2");
        keys.add("k4");
        List<String> strings = forValue.multiGet(keys);
        System.out.println(strings);

        System.out.println(forValue.setIfAbsent("k2", "v2"));

    }

}

使用redisTemplate该类可以存放任意类型的数据,但是该类型的数据必须实现序列,获取redis中对应的数据时,会进行反序列化。 如果使用RedisTemplate建议大家指定key,value,以及hashkey的序列化方式。

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600)) //缓存过期10分钟 ---- 业务需求。
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//设置key的序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) //设置value的序列化
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值