• Redis学习


    打算认真地系统地学习一下redis,本文为鉴,笑。

    先说认识

    这货是一个数据库,特点是:NoSQL + 内存型

    只是,其实多数人使用的都是“内存型”这个特性 -- 因为速度快,NoSQL 反而没那么显眼。

    当然,如果只是“内存型”,其实还有很多选择,例如ehcache、memcache等,甚至web应用的session也算一个,或者,还可以自己构建一个Map用于存取数据。

    之所以使用Redis,是因为它还提供了很多其他特性,例如多种数据格式、事务、集群、主从、持久化、订阅/发布等等。 -- 鉴于没有深入研究过ehcache、memcache,就不列出对比了。

    开始

    官方网站 redis.io 下载后,需要安装方可使用,详情请搜索之。--建议使用Linux运行,因为多数开源工具都优先支持Linux,总要接触的,不如直接开始。当然也有windows版本的,版本较旧就是。

    Linux下安装后的内容:

    [root@localhost redis-3.2.6]# cd /usr/local/bin/
    [root@localhost bin]# ll
    总用量 26344
    -rw-r--r--. 1 root root     377 12月 24 14:55 dump.rdb
    -rwxr-xr-x. 1 root root 5580287 12月 24 01:45 redis-benchmark
    -rwxr-xr-x. 1 root root   22177 12月 24 01:45 redis-check-aof
    -rwxr-xr-x. 1 root root 7826296 12月 24 01:45 redis-check-rdb
    -rwxr-xr-x. 1 root root 5708996 12月 24 01:45 redis-cli
    lrwxrwxrwx. 1 root root      12 12月 24 01:45 redis-sentinel -> redis-server
    -rwxr-xr-x. 1 root root 7826296 12月 24 01:45 redis-server
    [root@localhost bin]#

    需要说明的是,redis-server可以直接启动,但是仅限于本机使用。正确的启动方式应该附加配置文件redis.conf -- 可以在redis解压后的目录中找到,如下:

    [root@localhost bin]# ll ~/software/redis-3.2.6
    总用量 200
    -rw-rw-r--.  1 root root 80406 12月  6 16:38 00-RELEASENOTES
    -rw-rw-r--.  1 root root    53 12月  6 16:38 BUGS
    -rw-rw-r--.  1 root root  1805 12月  6 16:38 CONTRIBUTING
    -rw-rw-r--.  1 root root  1487 12月  6 16:38 COPYING
    drwxrwxr-x.  7 root root  4096 12月 24 01:42 deps
    -rw-rw-r--.  1 root root    11 12月  6 16:38 INSTALL
    -rw-rw-r--.  1 root root   151 12月  6 16:38 Makefile
    -rw-rw-r--.  1 root root  4223 12月  6 16:38 MANIFESTO
    -rw-rw-r--.  1 root root  6834 12月  6 16:38 README.md
    -rw-rw-r--.  1 root root 46695 12月  6 16:38 redis.conf
    -rwxrwxr-x.  1 root root   271 12月  6 16:38 runtest
    -rwxrwxr-x.  1 root root   280 12月  6 16:38 runtest-cluster
    -rwxrwxr-x.  1 root root   281 12月  6 16:38 runtest-sentinel
    -rw-rw-r--.  1 root root  7606 12月  6 16:38 sentinel.conf
    drwxrwxr-x.  2 root root  4096 12月 24 01:42 src
    drwxrwxr-x. 10 root root  4096 12月  6 16:38 tests
    drwxrwxr-x.  7 root root  4096 12月  6 16:38 utils
    [root@localhost bin]#

    但是,默认的配置仅限于回环访问,就是仅限于127.0.0.1访问,其他地址不行,所以需要修改一下(建议备份原有的)。

    [root@localhost redis-3.2.6]# cat redis.conf 
    # 许可IP
    bind 127.0.0.1
    # 监听端口
    port 6379
    
    tcp-backlog 511
    
    # 客户端空闲N秒后关闭连接(0是禁用)
    timeout 0
    
    tcp-keepalive 300
    
    # 是否改为守护进程
    daemonize no
    
    supervised no
    
    pidfile /var/run/redis_6379.pid
    
    loglevel notice
    
    logfile ""
    
    databases 16
    
    ################################ SNAPSHOTTING  ################################
    # 持久化(保存到硬盘上)
    # 900秒(15分钟)后,如果至少一个key发生改变
    save 900 1
    # 300秒(5分钟)后,如果至少十个key发生改变
    save 300 10
    # 50秒后,如果至少10000个key发生改变
    save 60 10000
    
    
    stop-writes-on-bgsave-error yes
    
    rdbcompression yes
    
    rdbchecksum yes
    # 持久化的目标文件名
    dbfilename dump.rdb
    
    # 持久化的目标目录
    dir ./
    
    
    
    # 主从
    slave-serve-stale-data yes
    
    slave-read-only yes
    
    repl-diskless-sync no
    
    repl-diskless-sync-delay 5
     
    repl-disable-tcp-nodelay no
     
    slave-priority 100
     
     
    ################################## SECURITY ###################################
    # 安全
    # 要求客户端在处理命令之前先AUTH <PASSWD>
    # 鉴于Redis非常快速,外部用户每秒可以尝试150K次密码,所以建议启用一个非常强壮的密码,否则很容易被破解。--本人建议配合bind使用或者仅使用bind。
    # 默认注释,即不需要密码。这里我给放开了,所以需要密码foobared
    requirepass foobared
    
    
    
    # maxclients 10000
    
    # maxmemory <bytes>
     
    # maxmemory-policy noeviction
     
    # maxmemory-samples 5
     
    appendonly no
    
    # The name of the append only file (default: "appendonly.aof")
    appendfilename "appendonly.aof"
    
    # appendfsync always
    appendfsync everysec
    # appendfsync no
     
    no-appendfsync-on-rewrite no
     
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
     
    aof-load-truncated yes
     
    # Set it to 0 or a negative value for unlimited execution without warnings.
    lua-time-limit 5000
    
    ################################ REDIS CLUSTER  ###############################
     
    # cluster-enabled yes
     
    # cluster-config-file nodes-6379.conf
     
    # cluster-node-timeout 15000
    
    # cluster-slave-validity-factor 10
     
    # cluster-migration-barrier 1
     
    # cluster-require-full-coverage yes
     
    
    ################################## SLOW LOG ###################################
     
    slowlog-log-slower-than 10000
     
    slowlog-max-len 128
    
    ################################ LATENCY MONITOR ##############################
     
    latency-monitor-threshold 0
    
    ############################# EVENT NOTIFICATION ##############################
     
    notify-keyspace-events ""
    
    ############################### ADVANCED CONFIG ###############################
     
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
     
    list-max-ziplist-size -2
     
    list-compress-depth 0
     
    set-max-intset-entries 512
     
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
     
    hll-sparse-max-bytes 3000
     
    activerehashing yes
     
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
     
    hz 10
     
    aof-rewrite-incremental-fsync yes

    以上是精简版,去掉了大段的英文注释。因为我使用了虚拟机+桥接方式,所以不能通过127.0.0.1:6379访问,所以放开了requirepass,这样就可以通过auth来验证了。

    数据格式

    Redis支持的数据格式有五种:string、list、hash、set、sortedset!

    需要注意的是,这些数据格式的 -- 本质上都是字节数组(byte[])!

    所以,Redis的任何一种格式都可以存储Java的所有的类型 -- 只要你将其转成字节数组 (byte[])!

    Java中对象转成字节数组(byte[])的方式,最基本的是通过ByteArrayOutputStream和ObjectOutputStream将实现了Serializable接口的类对象转成字节数组。如下:

    Person p = new Person();
    p.setName("小雯");
    p.setId("456321789");
    p.setAge(13);
    p.setWords("豆蔻年华二月初");
    
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
        objectOutputStream.writeObject(p);
        byte[] byteArray = out.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }

    或者,使用Jackson等序列化工具进行序列化 -- 更简洁明了,因为都是字符串。

    需要提一句,不建议使用ByteArrayOutputStream和ObjectOutputStream这种原始方式进行序列化,因为会序列化很多不必要的信息。以上面的代码为例,实际上我们只需要name、id、age、words这四个properties的信息就足够了,但原始的序列化还会附加很多信息(如继承的类、接口等等),这样会浪费时间和空间。

    所以,推荐使用Jackson、fastjson、gson等序列化工具。

    客户端

    Java的客户端推荐使用Jedis(其实我就知道这个),自带连接池、集群等配置,其方法与Redis完全一致。与Spring结合时可以使用RedisTemplate,类似RestTemplate。

    新建maven项目,添加依赖即可:

    <!-- jackson新版本 -->
    <!-- jackson-databind依赖core和annation,所以不必重复导入 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-joda</artifactId>
        <version>2.8.5</version>
    </dependency>
    
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>

    现在就可以使用Jedis了,先放一个小例子,后面详细研究下每种数据格式对应的方法。

    public class BasicDemo {
        private static final String PREFIX = "ABCDEF.";
        private static Jedis redis;
    
        // redis默认开启了保护,只允许本地回环连接请求(就是127.0.0.1),需要在redis.conf中修改。或设置密码、或bind许可ip。
        @Before
        public void setUp() {
            String host = "192.168.0.210";
            int port = 6379;
            redis = new Jedis(host, port);
            redis.auth("foobaredauth");
        }
    
        // STRING 操作 --TODO:实际上存储的是byte[],所以可以存储任意内容
        @Test
        public void string() {
    
            // SET key value: 将字符串值value关联到key。
            redis.set("name", "wangjun1");
            redis.set("id", "123456");
            redis.set("address", "guangzhou");
    
            // SETEX key seconds value :将值value关联到key,并将key的生存时间设为seconds(以秒为单位)。
            redis.setex("foo", 5, "haha");
    
            // MSET key value [key value ...] :同时设置一个或多个key-value对。
            redis.mset("haha", "111", "xixi", "222");
    
            // redis.flushAll();清空所有的key
            System.out.println(redis.dbSize());// dbSize是多少个key的个数
    
            // APPEND key value :如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
            redis.append("foo", "*00");// 如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
    
            // GET key 返回key所关联的字符串值
            String foo = redis.get("foo");
            System.out.println(foo);
    
            // MGET key [key ...] 返回所有(一个或多个)给定key的值
            List<String> list = redis.mget("haha", "xixi");
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        }
    }

    未完待续

    参考:

    Redis 命令参考

    为什么要选择使用 Redis ?

  • 相关阅读:
    .NET Core下的Socket示例.
    VS没办法调试,直接退出,报错:1. 使用调试生成配置或禁用调试选项“启用‘仅我的代码’”。。。
    2017年2月7日 今年第一天上班了
    .NET Core错误:The specified framework 'Microsoft.NETCore.App', version '1.0.0-rc2-3002702' was not found.
    KB2533623 下载
    Ajax Not Found,asp.net mvc 中
    JavaScript外部函数调用AngularJS的函数、$scope
    029医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------数据模型的分析(建表)
    028医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------需求分析
    50个查询系列-第10个查询:查询没有学全所有课的同学的学号、姓名;
  • 原文地址:https://www.cnblogs.com/larryzeal/p/6263124.html
Copyright © 2020-2023  润新知