Redis -----从入门到精通-----

        大家好,我是  爱耕田的码农  ,在这里首先祝大家每天开心,码农生活快乐,然后就是感谢各位朋友赏脸观看在下的文章,如有不妥,希望大家可以指出,最后感谢大家的点赞  关注   转发。

一.  NOSQL

        今天咱们学习redis,首先咱们先了解一下什么是NOSQL

1. NoSQL的引言

        NoSQL( Not  only SQL),意思是不仅仅是数据库,泛指非关系型数据库。Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨。

2. 为什么用NOSQL

        随着互联网网站的兴起,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,暴露了很多难以克服的问题。如商场网站中对商品数据频繁查询、对热搜商品的排行统计、订单超时问题、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。nosql这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。

3. NOSQL的四大分类

(1)键值(key - value)存储数据库

(2)列存储数据库

(3)文档型数据库

(4)图形数据库

---在这里就不做详细介绍了---

4.NOSQL应用场景

  • 数据模型比较简单

  • 需要灵活性更强的IT系统

  • 对数据库性能要求较高

  • 不需要高度的数据一致性

 二 . Redis

1. 什么是Redis

        Redis 是C语言开发的一个开源高性能键值对的内存数据库,可以用来做数据库、缓存、消息中间件等场景,是一种NoSQL(not-only sql,非关系型数据库)的数据库

2.Redis的优点

  • Redis是一个高性能key/value内存型数据库

  • Redis支持丰富的数据类型

  • Redis支持持久化

  • Redis单线程,单进程

三 . Redis安装和设置

1 . 安装redis依赖

Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖:

yum install -y gcc tcl

2.上传安装版并解压

上传到 /usr/local目录下

解压缩:

tar -xzf redis-6.2.6.tar.gz

进入redis目录:

cd redis-6.2.6

运行编译命令:

make && make install

如果没有出错,应该就安装成功了。

默认的安装路径是在 /usr/local/bin目录下:

该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:

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

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

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

3 . 启动 

redis的启动方式有很多种,例如:

  • 默认启动

  • 指定配置启动

  • 开机自启

(1)  默认启动

安装完成后,在任意目录输入redis-server命令即可启动Redis:

redis-server

 这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C则Redis停止。不推荐使用。

(2)指定配置启动

如果要让Redis以后台方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/usr/local/redis-6.2.6),名字叫redis.conf:

我们先将这个配置文件备份一份:

cp redis.conf redis.conf.bak

然后修改redis.conf文件中的一些配置:

# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
# 密码,设置后访问Redis必须输入密码
requirepass 123321

Redis的其它常见配置:

# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"

启动Redis:

# 进入redis安装目录 
cd /usr/local/bin
# 启动
./redis-server /usr/local/redis-6.2.6/redis.conf

(3)开机自启

我们也可以通过配置来实现开机自启。

首先,新建一个系统服务文件:

vi /etc/systemd/system/redis.service

内容如下:

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

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

[Install]
WantedBy=multi-user.target

然后重载系统服务:

systemctl daemon-reload

现在,我们可以用下面这组命令来操作redis了:

# 启动
service redis start 
# 停止
service redis stop
# 重启
service redis restart
# 查看状态
service redis  status

执行下面的命令,可以让redis开机自启:

systemctl enable redis

四 . Redis的五大数据类型

(1)String类型

(2)List类型

(3)Hash类型

(4)Set类型

(5)ZSet类型

-----这里就不一一介绍了-----

五 . 持久化机制

client redis[内存] -----> 内存数据- 数据持久化-->磁盘

Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是:

  • RDB 快照(Snapshot)

  • AOF (Append Only File) 只追加日志文件

1. 快照(Snapshot)

(1)特点

这种方式可以将某一时刻的所有数据都写入硬盘中,当然这也是redis的默认开启持久化方式,保存的文件是以.rdb形式结尾的文件因此这种方式也称之为RDB方式。

(2)快照生成方式

  • 客户端方式: BGSAVE 和 SAVE指令

  • 服务器配置自动触发

# 1.客户端方式之BGSAVE
- a.客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会调用fork来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。
    
    名词解释: fork当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写之后,对被写入的内存的共享才会结束服务` 

# 2.客户端方式之SAVE
- b.客户端还可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令

2 . AOF 只追加日志文件

(1) 特点

这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集.

2.开启AOF持久化

在redis的默认配置中AOF持久化机制是没有开启的,需要在配置中开启

# 1.开启AOF持久化
- a.修改 appendonly yes 开启持久化
- b.修改 appendfilename "appendonly.aof" 指定生成文件名称

3.日志追加频率

# 1.always 【谨慎使用】
- 说明: 每个redis写命令都要同步写入硬盘,严重降低redis速度

# 2.everysec 【推荐】
- 说明: 每秒执行一次同步显式的将多个写命令同步到磁盘

# 3.no	【不推荐】
- 说明: 由操作系统决定何时同步 

3 . AOF重写

(1)AOF带来的问题

AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件Redis提供了AOF重写(ReWriter)机制。

(2)AOF重写

用来在一定程度上减小AOF文件的体积

(3)触发重写方式
# 1.客户端方式触发重写
- 执行BGREWRITEAOF命令  不会阻塞redis的服务

# 2.服务器配置方式自动触发
- 配置redis.conf中的auto-aof-rewrite-percentage选项 参加下图↓↓↓
- 如果设置auto-aof-rewrite-percentage值为100和auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大
(4)重写原理

注意:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,替换原有的文件这点和快照有点类似。

五 . SpringBoot整合Redis

Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

注意: 使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口

1.引入依赖

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

<!-- spring2.X集成redis所需common-pool2-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.配置application.propertie

#Redis服务器地址
spring.redis.host=192.168.56.130
#Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123321
#Redis数据库索引(默认为0)
spring.redis.database= 0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

pom.xml修改打包插件

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.shared</groupId>
                        <artifactId>maven-filtering</artifactId>
                        <version>1.3</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>

使用RedisTemplate

    @SpringBootTest
class RedisdemoApplicationTests {

     @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Test
    void testList() {
        redisTemplate.opsForValue().set("name","张三");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }
}

控制台输出没有问题,但是软件中显示乱码了

所以我们需要配置redis的序列化

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 创建Template
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key和 hashKey采用 string序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
    

3 使用RedisTemplate

1 opsForValue

  @Test
    void testString() {
        redisTemplate.opsForValue().set("name","张三");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }

2 opsForHash

@Test
    void testHash() {
        redisTemplate.opsForHash().put("person","name","老韩");
        Object name = redisTemplate.opsForHash().get("person", "name");
        System.out.println(name);
    }

3 opsForSet

@Test
    void testSet(){
        redisTemplate.opsForSet().add("myFriend", "郝翊", "赵逸凡", "耿梦婷", "索伟", "谭智尤");
        redisTemplate.opsForSet().add("yourFriend", "郝翊", "武锦龙", "李明生", "索伟", "谭智尤");
        Set<Object> myFriend = redisTemplate.opsForSet().members("myFriend");
        Set<Object> difference = redisTemplate.opsForSet().difference( "yourFriend","myFriend");
        Set<Object> intersect = redisTemplate.opsForSet().intersect("myFriend", "yourFriend");
        System.out.println("我的好友:"+myFriend);
        System.out.println("你可能也认识:"+difference);
        System.out.println("你两共同的好友:"+intersect);
    }

4 opsForZSet

@Test
    void testZset(){
        redisTemplate.opsForZSet().add("leaderboard", "厨子哥",100);
        redisTemplate.opsForZSet().add("leaderboard", "张震",70);
        redisTemplate.opsForZSet().add("leaderboard", "冯杰",90);
        redisTemplate.opsForZSet().add("leaderboard", "曹璟昊",55);
        Set<Object> leaderboard = redisTemplate.opsForZSet().range("leaderboard", 0, -1);
        Long num = redisTemplate.opsForZSet().zCard("leaderboard");
        Set<Object> leaderboard1 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, -1);
        redisTemplate.opsForZSet().incrementScore("leaderboard", "曹璟昊", 50);
        Set<Object> leaderboard2 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, -1);
        System.out.println("参与选美的选手有:"+leaderboard+","+num+"个人");
        System.out.println("倒排:"+leaderboard1);
        System.out.println("加分后倒排:"+leaderboard2);
    }

5 opsForList

@Test
    void testList(){
        redisTemplate.opsForList().leftPush("lists", "苹果");
        redisTemplate.opsForList().leftPushAll("lists", "香蕉","哈密瓜");
        List<Object> lists = redisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(s-> System.out.println(s));
    }

七、 Redis 主从复制

1 主从复制

主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据

无法解决: 1.master节点出现故障的自动故障转移

2 搭建主从复制

service network restart

vi /usr/local/redis-6.2.6/redis.conf

# 1.准备3台机器并修改配置
- master
	port 6379
	bind 0.0.0.0
	
- slave1
	port 6379
	bind 0.0.0.0
	slaveof masterip masterport
	slaveof 192.168.56.171 6379

- slave2
	port 6379
	bind 0.0.0.0
	slaveof 192.168.56.171 6379


# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
# 密码,设置后访问Redis必须输入密码
requirepass 123321
	
bind 0.0.0.0
port 6379
daemonize yes
requirepass 123321





bind 0.0.0.0
port 6379
daemonize yes
replicaof 192.168.222.151 6379	
masterauth 123321
slaveof 192.168.222.151 6379
requirepass 123321



bind 0.0.0.0
port 6379
daemonize yes
replicaof 192.168.222.151 6379	
masterauth 123321
slaveof 192.168.222.151 6379
requirepass 123321
# 2.启动3台机器进行测试
- cd /usr/redis/bin
- ./redis-server /root/master/redis.conf
- ./redis-server /root/slave1/redis.conf
- ./redis-server /root/slave2/redis.conf

查看集群信息: info replication

八、Redis哨兵机制

1 哨兵Sentinel机制

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。简单的说哨兵就是带有自动故障转移功能的主从架构

无法解决: 1.单节点并发压力问题 2.单节点内存和磁盘物理上限

2 搭建哨兵架构

# 1.在主节点上创建哨兵配置
- 在Master对应redis.conf同目录下新建sentinel.conf文件,名字绝对不能错;

# 2.配置哨兵,在sentinel.conf文件中填入内容:
- sentinel monitor 被监控数据库名字(自己起名字) ip port 2
sentinel monitor mymaster 192.168.222.151 6379 1
sentinel auth-pass mymaster 123321

# 3.启动哨兵模式进行测试
./redis-sentinel  /usr/local/redis-6.2.6/sentinel.conf 

说明:这个后面的数字2,是指当有两个及以上的sentinel服务检测到master宕机,才会去执行主从切换的功能。

id 越小 优先权越大

偏移量越大,优先权越高。

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值