Redis知识点总结

23 篇文章 3 订阅

Redis优势:

  1. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  2. 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  3. 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  4. 丰富的特性 – Redis还支持 publish/subscribe 通知, key 过期等等特性
  5. 支持事务

与memcached相比:
1. memcached所有的值均是简单字符串,redis支持丰富的数据类型
2. redis速度比memcached快很多
3. redis可持久化其数据

Redis支持五种数据类型:string(字符串)、hash(map< string, string>)、list(链表)、set(没有排序的集合)、zset(有序集合)

redis客户端连接:
redis-cli -h 127.0.0.1 -p 6380
redis客户端连接集群:
redis-cli -c -h 127.0.0.1 -p 6379

Redis多数据库操作:

主要为了防止key冲突问题,默认情况下,客户端连接到数据库0,可通过修改配置文件redis.conf下的参数来进行修改:
databases 16
可通过select <数据库ID>来进行修改,每个数据库都有自己单独的空间,不用担心key冲突问题。

例子

key相关命令

flushdb           #清空当前选择的数据库
flushall            #清空所有数据库
move key1 1        #将当前数据库的key1移动到ID为1的数据库中
rename oldkey newkey   #将oldkey改名为newkey
renamenx oldkey newkey  #如果newkey已存在,则无效
expire key 1 100       #把key1的过期时间设置为100秒
persist key1          #把key1的超时去掉,变成持久化的键
keys my*          #获取数据库中以my开头的key
exists key1         #存在key1返回1,否则返回0
select 0            #打开ID为0的数据库

Java连redis集群的例子:

RedisClusterConnection.java

public class RedisClusterConnection {
    private static Logger LOG = LogManager
        .getLogger(RedisClusterConnection.class);

    private static JedisCluster jedisCluster;

    private static Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

    private static Set<HostAndPort> parseHostAndPort() {
        InputStream in = null;
        try {
            Properties properties = new Properties();
            in = ClassLoader.getSystemClassLoader().getResourceAsStream(
                    "redis-config.properties");
            properties.load(in);
            Set<HostAndPort> haps = new HashSet<HostAndPort>();
            for (Object key : properties.keySet()) {
                if (!key.toString().startsWith("redis.address")) {
                    continue;
                }
                String val = properties.get(key).toString();
                boolean isIpPort = p.matcher(val).matches();
                if (!isIpPort) {
                    throw new IllegalArgumentException("ip 或 port 不合法");
                }

                String[] ipAndPort = val.split(":");
                HostAndPort hap = new HostAndPort(ipAndPort[0],
                        Integer.parseInt(ipAndPort[1]));
                haps.add(hap);
            }
            return haps;
        } catch (InvalidPropertiesFormatException e) {
            LOG.error(e);
        } catch (IOException e1) {
            LOG.error(e1);
        } catch (Exception e2) {
            LOG.error(e2);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static JedisCluster getInstance() {
        Set<HostAndPort> haps = parseHostAndPort();
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(1024);
        poolConfig.setMaxIdle(10);
        poolConfig.setMaxWaitMillis(1800000L);
        poolConfig.setTimeBetweenEvictionRunsMillis(180000L);
        poolConfig.setTestOnBorrow(true);

        jedisCluster = new JedisCluster(haps, poolConfig);
        return jedisCluster;
    }

    public static void main(String[] args) {
        Set<HostAndPort> set = parseHostAndPort();
        Iterator<HostAndPort> iterator = set.iterator();
        while (iterator.hasNext()) {
            HostAndPort hap = iterator.next();
            System.out.println(hap.getHost() + ":" + hap.getPort());
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

redis-config.properties

#redis集群
redis.address1=192.168.0.1:6379
redis.address2=192.168.0.1:6380
redis.address3=192.168.0.1:6381
redis.address4=192.168.0.1:6382
redis.address5=192.168.0.1:6383
redis.address6=192.168.0.1:6384
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Redis持久化方式:

  1. RDB
    在指定时间间隔内生成数据集的时间点快照。
     优点:RDB是一个非常紧凑的文件,它保存了Redis在某个时间点上的数据集。非常适合用于进行备份:比如:每小时备份一次RDB文件,遇上问题可随时还原数据集到不同的版本。非常适合灾难恢复:它只有一个文件,并且内容紧凑,可传输到其他地方。RDB在恢复大数据集时的速度比AOF的恢复速度快;RDB可最大化redis性能,父进程保存RDB文件时要做的是fork一个子进程,然后子进程处理接下来的保存操作,父进程无须执行任何磁盘I/O操作。
     缺点:如需要尽量避免在服务器故障时丢失数据,RDB不适合。每隔一段时间保存数据集的状态,一旦故障会丢失这部分数据。每次保存RDB时,redis都要fork()一个子进程,并由子进程进行实际的持久化工作。在数据集庞大时,fork()会很耗时,造成服务器在某毫秒内停止处理客户端。
     
    redis.conf里rdb相关配置:
    save 900 1 # 900秒有1个更改,进行数据同步
    save 300 10 # 300秒有10个更改,进行数据同步
    save 60 10000 # 60秒有10000更改,进行数据同步
    dbfilename dump.rdb # 指定rdb备份数据的文件名

  2. AOF
    记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据库
     优点:让redis更耐久,你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
     缺点:对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。

    redis.conf里AOF的相关配置:
     appendonly yes //启用aof持久化方式
     appendfilename appendonly.aof // 更新日志文件名,默认为appendonly.aof
     appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
     appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
     appendfsync no //完全依赖os,性能最好,持久化没保证

Redis备份与恢复

save、bgsave ——备份
config get dir ——得到redis安装目录
此时在redis安装目录下会有一个“dump.rdb”文件,将此文件拷贝到redis安装目录,重新启动redis即可。启用AOF后会在安装目录生成“appendonly.aofappendonly.aof”文件,AOF文件拷贝到redis安装目录即可。

redis工具

redis-benchmark:性能检测工具
-h <hostname>      Server hostname (default 127.0.0.1)  
-p <port>          Server port (default 6379)  
-s <socket>        Server socket (overrides host and port)  
-c <clients>       Number of parallel connections (default 50)  
-n <requests>      Total number of requests (default 10000)  
-d <size>          Data size of SET/GET value in bytes (default 2)  
-k <boolean>       1=keep alive 0=reconnect (default 1)  
-r <keyspacelen>   Use random keys for SET/GET/INCR, random values for SADD  
  Using this option the benchmark will get/set keys  
  in the form mykey_rand:000000012456 instead of constant  
  keys, the <keyspacelen> argument determines the max  
  number of values for the random number. For instance  
  if set to 10 only rand:000000000000 - rand:000000000009  
  range will be allowed.  
-P <numreq>        Pipeline <numreq> requests. Default 1 (no pipeline).  
-q                 Quiet. Just show query/sec values 只显示每秒钟能处理多少请求数结果  
--csv              Output in CSV format  
-l                 Loop. Run the tests forever 永久测试  
-t <tests>         Only run the comma separated list of tests. The test  
                    names are the same as the ones produced as output.  
-I                 Idle mode. Just open N idle connections and wait.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
redis-check-dump

作用:检查本地数据文件
redis-check-dump dump.rdb
redis-check-dump例子

redis-check-aof

作用:更新日志检查,加–fix 进行修复
redis-check-aof appendonly.aof
redis-check-aof例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值