zoukankan      html  css  js  c++  java
  • Redis学习笔记(3)

    Redis事务

    对于一组命令,按顺序地串行化执行而不会被其他命令插入,不允许加塞

    主要命令:MULTI、EXEC、DISCARD、WATCH、UNWATCH

    • 正常执行:MULTI [指令集] EXEC
    • 放弃事务:MULTI [指令集] DISCARD
    • 当一系列指令中有某条指令有编译错误(例如无法识别的命令)时,整个事务中所有指令都无法执行
    • 当一系列指令中有某条指令有运行错误(例如对字符串采取自增操作)时,事务中只有该指令无法执行

    因此可以说,Redis对事务是部分支持的

    没有隔离级别的概念,不保证原子性

    WATCH监控

    WATCH [key] MULTI [指令集] EXEC

    WATCH key[key1 key2 ...]

    监视一个或多个key,如果在事务执行前这些key的值被其他命令更改,那么这个事务将被放弃

    可以通过UNWATCH取消对所有key的监控后再重新WATCH

    Redis的发布和订阅

    是进程间的一种消息通信模式:pub发送消息,sub接收消息

    先订阅后发布:

    SUBSCRIBE c1 c2 s*(可使用通配符*)

    PUBLISH c2 hello

    PUBLISH s1 pattern-hello

    Redis的复制

    即主从复制,主机(Master)数据更新后根据既定策略同步数据到备机(Slave),Master主写,Slave主读

    作用:读写分离、容灾

    从库配置:SLAVEOF 主机IP 主机port

    配置步骤

    1. 拷贝redis.conf文件
    2. 开启daemonize为yes
    3. 修改pid文件名
    4. 修改端口
    5. 修改log文件名
    6. 修改dump.rdb文件名

    开启服务后:

    ​ 使用 info replication 查看主从复制信息

    ​ Slave连接主机,如:SLAVEOF 127.0.0.1 6379

    Slave覆写Master已有的key时:

    (error)READONLY You can't write against a read only slave

    不同情景

    一主多仆:

    1. Master shutdown后,Slave保持待命,且连接状态变为down
      Master重启后,主从关系不变,Slave仍可正常工作
    2. Slave shutdown之后,其他Slave正常工作
      Slave重启后,身份变化为Master,需要重新与原Master连接
      重连后shutdown过程中Master写入的数据在Slave中仍可正常访问

    接力传递:

    某一台机器既作为Slave又作为Master,该机器调用info replication指令显示的role仍然为Slave

    主从切换:

    Slave1成为新主机:SLAVEOF no one

    Slave2连接新主机:SLAVEOF [Slave1.IP] [Slave1.port]

    哨兵模式

    主从切换的自动版。能够后台监控主机是否故障,如果故障了可以通过投票数自动将备机转化为主机

    1. 新建sentinel.conf文件
    2. sentinel monitor [主机名随便取] [主机IP] [主机端口] 1(最后的1代表Slave票数多于1票即可转化为Master)
    3. 启动哨兵:redis-sentinel redis/sentinel.conf

    主机挂掉之后,某个Slave成为主机,其他Slave调整跟随对象。原主机重启后成为Slave

    Jedis

    Jedis初始化

    Jedis jedis = new Jedis("127.0.0.1", 6379);
    System.out.println(redis.ping());
    

    Jedis事务

    Transaction transaction = jedis.multi();
    transaction.set("k1", "v1");
    transaction.set("k2", "v2");
    transaction.exec();
    // transaction.discard();
    

    watch过程中key的值被其他线程修改时,transaction.exec()会返回null,可通过这一点判断事务是否成功执行

    // ...
    jedis.watch("k1");
    if (condition == false){
        jedis.unwatch();
        return false;
    }else {
        Transaction transaction = jedis.multi();
        // ...
        return transaction.exec() != null;
    }
    

    主从复制

    Jedis master = new Jedis("127.0.0.1", 6379);
    Jedis slave = new Jedis("127.0.0.1", 6380);
    slave.slaveof("127.0.0.1", 6379);
    master.set("key", "读写分离");
    // 由于内存读写极快,这里slave马上get可能会获得空值或旧值
    System.out.println(slave.get("key"));
    

    Jedis Pool

    使用单例模式返回Jedis池的唯一实例

    // ···单例模式返回
    public static JedisPool getJedisPoolInstance{
        if(...){
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxIdle(32);
            poolConfig.setMaxWaitMillis(60 * 1000);
            // 池配置...
            jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
        }
        return jedisPool;
    }
    
    // 释放
    public static void release(JedisPool jedisPool, Jedis jedis){
        if(jedis != null){
            jedisPool.returnResourceObject(jedis);
        }
    }
    
    
  • 相关阅读:
    python_面向对象——多态
    python_面向对象——封装
    python_面向对象——多继承
    python_面向对象——继承
    python_面向对象——对象间的组合关系
    python_面向对象——类之间的依赖关系
    python_面向对象——对象之间的关联关系
    python_异常处理
    python_反射:动态导入模块
    python_网络编程socketserver模块实现多用户通信
  • 原文地址:https://www.cnblogs.com/2511zzZ/p/13080268.html
Copyright © 2011-2022 走看看