Redis

Posted xue_yun_xiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis相关的知识,希望对你有一定的参考价值。

一、java 操作 redis

1、创建Java 工程 ,并导入依赖

 <dependencies>

        <!--    1、 Jedis
            reidis  java 客户端
        -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--    2、 Junit测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>


        <!-- 导入fastJSON -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

    </dependencies>

2、测试

public class RedisTest 

    private  Jedis jedis;

    @Before
    public  void init()
        // redis 客户端
        jedis = new Jedis("192.168.12.133", 6379);
    

    @Test
    public void stringTest()

        // String host,  redis 域名/ iP  192.168.12.133
        // int port  redsi 端口号 6379


        String result =   jedis.set("name", "xiaocui");
        System.out.println("result = " + result);

        String name = jedis.get("name");
        System.out.println("name = " + name);


        jedis.expire("name", 20);

    


    @Test
    public  void  hashTest()

        // 存储对象
        jedis.hset("student1", "name", "xiaoming");
        jedis.hset("student1", "sex", "F");
        jedis.hset("student1", "age", "18");


        String name = jedis.hget("student1", "name");
        System.out.println("name = " + name);

        Map<String, String> map = jedis.hgetAll("student1");

        System.out.println("map = " + map);

    

    /**
     * 保存对象
     */
    @Test
    public void saveObject()

        Student student = new Student();

        student.setId(999);
        student.setName("xiaoming");

        // 将对象转换为 json
        jedis.set("student_xiaoming", JSON.toJSONString(student));

        String jsonStr = jedis.get("student_xiaoming");


        Student student1  = JSON.parseObject(jsonStr,Student.class);

        System.out.println("student1 = " + student1);
    


    /**
     * 连接池 测试
     */
    @Test
    public  void  poolTest()

        GenericObjectPoolConfig config =  new GenericObjectPoolConfig();

        config.setMaxIdle(20);
        config.setMinIdle(10);
        config.setMaxTotal(100);

        config.setMaxWaitMillis(3000);

        //创建连接
        JedisPool jedisPool = new JedisPool(config,"192.168.12.133",6379);

        // 获取一个链接
        Jedis jedis =   jedisPool.getResource();



        String result =   jedis.set("name", "xiaocui");
        System.out.println("result = " + result);

        String name = jedis.get("name");
        System.out.println("name = " + name);


        // 关闭连接池
        jedisPool.close();

    


    @After
    public void  destroy()

        jedis.close();;
    

二、Redis持久化机制(重要)

Redis持久化机制:Redis 是基于内存的缓存,所有数据都存到内存,但是redis也会将数据存储到硬盘,以便于关机再开机可以立即回复数据。

存储数据的形式:

RDB:

默认存储形式,RDB就是redis 内存数据做的一个镜像 存储到磁盘

  • RDB持久化的时机:
    save 900 1:在900秒内,有1个key改变了,就执行RDB持久化。
    save 300 10:在300秒内,有10个key改变了,就执行RDB持久化。
    save 60 10000:在60秒内,有10000个key改变了,就执行RDB持久化。

RDB无法保证数据的绝对安全。
假如配置 save 300 10 如果 300s 之内 ,有10个key改变了,就执行RDB持久化,生成新的 rdb 文件。
如果 300s 之内 ,有5个key改变了,不会rdb,此时 突然机器宕机(关机),5个改变的key 发生数据丢失

特点

  • 每隔一段时间生成rdb,如果rdb 比较大,会相当耗费性能
  • 在一个特定时间段内,发生宕机,数据会有部分丢失
  • 宕机之后,恢复数据,很快(rdb本身就是内存映射数据)

AOF

aof 就是一个文件,redis会将所有用户执行的 增删改 命令记录下来,写入一个aof 文件中
aof 默认是 不开启,官方推荐 rdb 和 aof 同时使用

AOF持久化时机:
appendfsync always:每执行一个写操作,立即持久化到AOF文件中,性能比较低。
appendfsync everysec:每秒执行一次持久化。
appendfsync no:会根据你的操作系统不同,环境的不同,在一定时间内执行一次持久化。

特点

  • 几乎可以做到不丢失数据
  • ao’f 宕机之后 恢复慢
  • 相对于 rdb 来说,持久化性能 耗费较少

实际开发过程中连个同时开启,redis会优先使用aof

测试

前提先将其他redis 容器删除

[root@mastera java2102]# cd docker-compose-redis01/
[root@mastera docker-compose-redis01]# docker-compose down
Stopping redis ... done
Removing redis ... done
Removing network docker-compose-redis01_default
[root@mastera docker-compose-redis01]# cd ../
[root@mastera java2102]# ls
docker-compose-redis01  docker-compose-test1

1、创建文件夹 及文件

[root@mastera java2102]# mkdir docker-compose-redis02
[root@mastera java2102]# cd docker-compose-redis02
[root@mastera docker-compose-redis02]# vim docker-compose.yaml
version: '3.1'
services:
  redis:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 6379:6379
    volumes:
      - ./conf/redis.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]

2、在docker-compose.yaml 目录下创建conf

[root@mastera docker-compose-redis02]# mkdir conf[root@mastera docker-compose-redis02]# cd conf/[root@mastera conf]# vim redis.conf
save 300 10
#开启aop
appendonly yes
appendfsync always

3、启动

[root@mastera conf]# cd ../
[root@mastera docker-compose-redis02]# docker-compose up
Creating network "docker-compose-redis02_default" with the default driver

三、redis 集群模式(重要)

单机redis缺点:
1.单点故障
2.读写性能 11w 8w 读写性能有限(cpu 网卡 内存)
3.故障恢复慢,需要人工介入,有可能数据丢失

主从模式

特点
主机负责 读写,从机只负责读 —》读写性能增加
从机数据和主机保持一致 -----》防止数据丢失,主机挂了,从机可以立即配置为主机上位 一定程度上解决单点故障
缺点
主机挂了,不可以自动切换
整体集群 内存大小限定 48G 68G

哨兵模式

哨兵模式:可以做到maste(主节点) 挂了,自动选举slaver(从节点) 做主节点,保证服务高可靠

缺点
只有主机读写,当前master 节点内存容量 决定整个集群容量

去中心化模式

有多个主节点,每个主节点 只负责读写 一部分数据
三主三从

优点
有主从,可以自动切换,数据不丢失,服务不停止
大大读写性能 内存容量也可以成倍数增加
数据槽(slot):去中心化模式 每格master 存储数据的一个位置 总共 16384个
作用:存储数据 便于迁移数据

测试

主从模式

1、

[root@mastera java2102]# mkdir docker-compose-redis03
[root@mastera java2102]# cd docker-compose-redis03
[root@mastera docker-compose-redis03]# 
[root@mastera docker-compose-redis03]# vim docker-compose.yaml
version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis1
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7001:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis2
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7002:6379
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis3
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 7003:6379
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]

2、创建conf 及内部的 redis1.conf redis2.conf redis3.conf

[root@mastera docker-compose-redis03]# mkdir conf
[root@mastera docker-compose-redis03]# cd conf/
[root@mastera conf]# vim redis1.conf
[root@mastera conf]# vim redis2.conf 

redis1.conf

save 300 10
#开启aop
appendonly yes
appendfsync always

redis2.conf redis3.conf

save 300 10
#开启aop
appendonly yes
appendfsync always
# redis2和redis3从节点配置
replicaof master 6379

3、启动

[root@mastera conf]# ls
redis1.conf  redis2.conf  redis3.conf
[root@mastera conf]# cd ../
[root@mastera docker-compose-redis03]# docker-compose up

4、测试

去中心化模式

1、创建docker-compose.yaml

[root@mastera java2102]# mkdir docker-compose-redis04
[root@mastera java2102]# cd docker-compose-redis04
[root@mastera docker-compose-redis04]# vim docker-compose.yaml




登陆reids

root@ad585d764f14:/data# redis-cli -c -h 192.168.12.130 -p 7001

-c  已集群模式登陆
-h   设置当前登陆 主机
-p 7001  指定登陆的端口号

以上是关于Redis的主要内容,如果未能解决你的问题,请参考以下文章

layoutSubviews drawRect调用时机

JVM类加载的时机

GC的时机

setTimeout-的执行时机

redis持久化

随想006:帮忙的时机