• Redis的安装使用


    1.Redis是什么

    Redis是一个使用ANSI C(C语言) 编写的开源的高性能的Key-Value的NoSQL数据库(非关系型数据库)。
     

    2.Redis特点

    1.基于内存
    2.可持久化数据
    3.具有丰富的数据结构类型,适应非关系型数据的存储需求
    4.支持绝大多数主流开发语言,如C、C++、Java、Python、R、JavaScript等。
    5.支持集群模式,高效、稳定。
     

    3.数据模型(A)

    1.键值对形式。
    2.Redis的数据结构类型,指的就是Redis值的结构类型。
    0

    4.Redis作用

    1.本质是数据库,能存储数据。
    Redis能灵活处理非关系型数据的读、写问题,是对MySQL等关系型数据库的补充。
    新浪微博就是使用Redis集群做数据库。
     
    2.缓存数据。
    所谓缓存,就是将数据加载到内存中后直接使用,而不是每次都通过IO流从磁盘上读取。好处:读写效率高。
    而Redis则是将数据直接存储在内存中,只有当内存空间不足时,将部分数据持久化到磁盘上。
     

    5.Redis安装(Linux)

    Redis官方只提供了源码,并没有提供经过编译之后的安装包。因此,安装Redis,要先编译、后安装。(即源码安装方式)
     

    5.1 redis安装步骤

    1.下载,上传到Linux服务器,并解压
    2.预编译(实际上是检查编译环境的过程)
    进入目录: cd /opt/soft/redis-3.2.9/deps/jemalloc
    执行预编译 ./configure
    在预编译的过程中,会检测安装redis所需的相关依赖,依次安装即可。
    如:缺少c编译环境 yum -y install gcc-c++
     
    预编译不是必须的步骤,它只是在检查编译过程中需要的环境是否满足。通常源码包中,都有一个可执行的configure脚本,这个脚本执行预编译的脚本。但是有一些源码包中,没有该文件,可以省略预编译步骤。
     
    3.编译 进入/opt/soft/redis-3.2.9/src
    make
    4.安装 进入/opt/soft/redis-3.2.9/src
    make install
    5.启动redis服务端(指定配置文件)
    拷贝redis.conf文件到/etc 目录下,方便管理。
    cp /opt/soft/redis-3.2.9/redis.conf /etc/
    /usr/local/bin/redis-server /etc/redis.conf
     
    0
    6.启动redis客户端,登陆 /usr/local/bin/redis-cli
    0
     

    6.redis.conf常用配置说明

    6.1 requirepass (设置密码)

    给redis设置密码
    在/etc/redis.conf中设置密码(退出redis登录用quit)
    0
    找到上面这行代码改成
    0
    设置密码后需要重新启动redis服务端 才会生效
     
    在客户端使用auth命令,验证密码。
    0
     

    6.2 databases(数据库)

    Redis默认有16个数据库,寻址角标从0开始。
    默认连接db0
    0
    客户端使用select命令可切换数据库
    0
     

    6.3 port(端口)

    指定redis的服务端口,默认6379
    0
     

    6.4 daemonize(后台进程)

    Redis默认关闭后台进程模式,改成yes,redis服务在后台启动。
    0
     
     

    6.5 loglevel(日志级别)

    0
     

    6.6 logfile(日志输出文件)

    Redis日志输出目录,默认不输出日志到文件。
    0
     

    6.7 dbfilename(持久化文件名)、 dir(文件路径)

    指定数据持久化的文件名及目录。
    0
     

    7.将redis添加为系统服务

    7.1 第一步:开启后台模式

    修改配置文件,将daemonize改为yes
     

    7.2 第二步:创建shell脚本

    Linux系统服务,在/etc/init.d目录下创建redis脚本
    ###########################
    #chkconfig: 2345 10 90
    #description: Start and Stop redis
    PATH=/usr/local/bin:/sbin:/usr/bin:/bin
       
    REDISPORT=6379
    EXEC=/usr/local/bin/redis-server
    REDIS_CLI=/usr/local/bin/redis-cli
    ##判断redis是否启动了 
    PIDFILE=/var/run/redis_6379.pid
    CONF="/etc/redis.conf"
    PASSWORD=$(cat $CONF|grep '^s*requirepass'|awk '{print $2}'|sed 's/"//g')
       
    case "$1" in
        start)
            if [ -f $PIDFILE ]
            then
                    echo "$PIDFILE exists, process is already running or crashed"
            else
                    echo "Starting Redis server..."
                    $EXEC $CONF
            fi
            if [ "$?"="0" ]
            then
                  echo "Redis is running..."
            fi
            ;;
        stop)
            if [ ! -f $PIDFILE ]
            then
                    echo "$PIDFILE does not exist, process is not running"
            else
                    PID=$(cat $PIDFILE)
                    echo "Stopping ..."
    if [ -z $PASSWORD ]
    then 
        $REDIS_CLI -p $REDISPORT shutdown
    else
        $REDIS_CLI -a $PASSWORD -p $REDISPORT shutdown
    fi
                    #$REDIS_CLI -p $REDISPORT SHUTDOWN
                    while [ -x ${PIDFILE} ]
                   do
                        echo "Waiting for Redis to shutdown ..."
                        sleep 1
                    done
                    echo "Redis stopped"
            fi
            ;;
       restart|force-reload)
            ${0} stop
            ${0} start
            ;;
      *)
        echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
            exit 1
    esac
    ##############################

    7.3 第三步:添加shell脚本可执行权限

    chmod +x /etc/init.d/redis

    7.4 第四步:添加Redis开机启动

    7.4 第四步:添加Redis开机启动

    8.Redis的值(value)的数据结构类型

    一般说Redis的数据结构类型,指的就是redis的值value的类型;
    Redis常用的数据结构类型:string、list、set、sortedSet、hash
     

    9.Redis的使用

    9.1 key的类型

    redis的key 值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如”foo”的简单字符串到一个JPEG文件的内容都可以。空字符串也是有效key值。
    redis建议使用字符串做为key的类型
     

    9.2 key取值规范

    1.键值不需要太长,消耗内存,在数据中查找这类键值的计算成本较高
    2.键值不宜过短,可读性较差,通常建议见名知意。
    例:user:id:1:username;user:id:1:password 。通过user:id:1*查询。这就是一种命名方式(不一定要使用这种方式)
     

    9.3 Key命令

    9.4 string类型

    string类型是redis最常用的数据结构类型,存储的值为字符串。

    string类型相关命令

    String类型的应用场景

    1.做与统计有关的业务,如新浪微博(微信朋友圈)中的点赞功能
    2.解决多线程的线程安全问题。
    Redis的key是单线程模式,这就意味一瞬间只有一个线程能够持有这个key,所以可以使用redis解决部分涉及线程安全的业务,比如说抢购、秒杀。
    再比如学习多线程时模拟买票窗口的卖票业务。
     

    9.5 List类型

     

    特点:

    1.基于Linked List实现
    2.元素是字符串类型
    3.列表头尾增删快,中间增删慢,增删元素是常态
    4.元素可以重复出现
    5.最多包含2^32-1元素
    列表的索引:从左至右,从0开始;从右至左,从-1开始
     

    List类型相关命令

    List类型应用场景

    1.处理排名类业务。如新浪微博评论、论坛回帖楼层等。
    2.聊天室
     

    9.6 Hash类型(散列)

     

    特点

    0
    1.由Field(字段)和与之关联的value组成map键值对
    2.field和value是字符串类型;
    3.一个hash中最多包含2^32-1键值对。
     

    Hash相关命令

    Hash的作用

    节约内存空间:
    redis每创建一个键,都会为这个键储存一些附加的管理信息(比如这个键的类型,这个键最后一次被访问的时间等等)可以说redis的key相对于值来说,更珍贵!所以数据库里面的键越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,在获取key对应的value值时cpu的开销也会更多 。
    Hash结构可以将具有关联关系的一组key-value,存储到同一个hash结构中,从而减少key的数量。所以在能使用hash的时候尽量使用hash。
     
    不适合使用Hash的场景
    在需要只对hash中某个字段设置过期时,就不建议使用hash。Redis的key的过期功能只能对键操作,而Hash结构不能单独对某一个filed设置过期功能。
     

    9.7 Set类型(集合)

    特点

    1.无序的、去重的;
    2.元素是字符串类型;
    3.最多包含2^32-1元素。
     

    Set相关命令

    Set应用场景

    新浪微博的共同关注:当用户访问另一个用户的时候,会显示出两个用户共同关注哪些相同的用户(交集)
     

    9.8 SortedSet类型(有序集合)

    特点

    1.类似Set集合;
    2.有序的、去重的;
    3.元素是字符串类型;
    4.每一个元素都关联着一个浮点分数值(Score),并按照分数值从小到大的顺序排列集合中的元素。分数值可以相同,相同时按字典顺序排列
    5.最多包含2^32-1元素
     

    SortedSet类型相关命令

    SortedSet类型适用场景

    适用于需要有序且唯一的业务或操作:
    如,网易音乐排行榜:
    每首歌的歌名作为元素(唯一、不重复)
    每首歌的播放次数作为分值
    用zrevrange来获取播放次数最多的歌曲(就是最多播放榜了,云音乐热歌榜,没有竞价,没有权重)
     

    10.使用Jedis连接redis服务器

    Jedis是Redis官方推荐的Java连接开发工具,可以通过java代码操作redis数据库,就类似于jdbc
     

    10.1 使用jedis连接redis可能会出现的问题及解决方案:

    1.ip绑定问题
    0
    使用Jedis连接redis服务器需要把Redis的配置文件redis.conf里的bind 127.0.0.1(或bind localhost)注释掉,这句话的意思是仅允许本机才能访问。我们需要让redis服务器允许其他主机访问
    0
     
    2.保护模式(如果设置了密码可以进行密码验证,不用关闭保护模式)
    DENIED Redis is running in protected mode because protected mode is enabled…
    关闭保护模式:把Redis的配置文件redis.conf中的protected-mode 的yes改成no
    0
     

    10.2 Jedis 相关jar包导入

     
    0
     

    10.3 Jedis连接redis服务端

    package com.gjs.jedis;
    
    import org.junit.Test;
    
    import redis.clients.jedis.Jedis;
    
    public class TestJedis {
        
        @Test
        public void testJedisConnect() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            jedis.auth("1234"); //登录验证
            
            //测试连接
            System.out.println("redis服务器是否运行:"+jedis.ping());
            System.out.println("redis服务器信息:"+jedis.info());
            
            //关闭连接
            jedis.close();
        }
    }

    10.4 Key测试

    jedis类中大部分方法名都与对应的命令同名
    @Test
        public void testKey() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            //登录验证
            jedis.auth("1234");
    
            jedis.set("name", "zhangsan");//加入数据
            System.out.println("获取key对应的值:"+jedis.get("name"));
            Set<String> keys = jedis.keys("*");//使用通配符进行模糊查询
            System.out.println("获取所有key的值:"+keys);
            //关闭连接
            jedis.close();        
        }

    10.5 List测试

    @Test
        public void testList() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            //登录验证
            jedis.auth("1234");    
            
            jedis.lpush("list", new String[] {"a","c","b"});//添加数据
            Long len = jedis.llen("list");//获取长度
            System.out.println("list长度:"+len);
            System.out.println("list元素:"+jedis.lrange("list", 0, len));
            System.out.println("指定索引位置的元素:"+jedis.lindex("list", 1));
            
            //关闭连接
            jedis.close();        
        }

    10.6 Hash测试

    @Test
        public void testHash() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            //登录验证
            jedis.auth("1234");    
            //添加数据
            jedis.hset("user", "id", "1");
            jedis.hset("user", "name", "zhangsan");
            jedis.hset("user", "password", "123456");
            //获取所有元素
            Map<String, String> user = jedis.hgetAll("user");
            System.out.println("获取hash的所有字段值:"+user);
            
            //关闭连接
            jedis.close();        
        }

    10.7 Set测试

        @Test
        public void testSet() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            //登录验证
            jedis.auth("1234");    
            //添加数据
            jedis.sadd("set1",new String[] {"a","s","d","f","g"});
            jedis.sadd("set2", new String[] {"a","s","z","x"});
            //获取所有元素
            Set<String> set1 = jedis.smembers("set1");
            System.out.println("获取set的所有元素:"+set1);
            
            System.out.println("获取元素数量:"+jedis.scard("set1"));
            
            //获取交并补集,方法参数是可变的
            Set<String> inter = jedis.sinter("set1","set2");
            System.out.println("获取交集:"+inter);
            Set<String> union = jedis.sunion("set1","set2");
            System.out.println("获取并集:"+union);
            Set<String> diff = jedis.sdiff("set1","set2");
            System.out.println("获取差集:"+diff);
            
            //关闭连接
            jedis.close();        
        }

    10.8 SortedSet测试

        @Test
        public void testSortedSet() throws Exception {
            //创建客户端指定连接服务器端主机ip和端口,端口不指定时默认使用6379
            Jedis jedis = new Jedis("192.168.192.128", 6379);
            System.out.println("连接redis服务器端成功!");
            //登录验证
            jedis.auth("1234");    
            
            //添加数据
            Map<String, Double> scoreMembers = new HashMap<>();
            scoreMembers.put("a", 1d);
            scoreMembers.put("b", 3d);
            scoreMembers.put("c", 2d);
            jedis.zadd("sortSet", scoreMembers);
            //获取数据
            //获取分数值在指定区间的元素并按分数值由小到大排序
            Set<String> zrange = jedis.zrange("sortSet", 0, 3);
            System.out.println(zrange);
            
            //关闭连接
            jedis.close();        
        }

    11.Redis持久化

    Redis持久化,就是将内存中的数据,永久保存到磁盘上。
    Redis持久化有两种方式:RDB(Redis DB)、AOF(AppendOnlyFile)。
     

    11.1 RDB(快照模式)

    在默认情况下,Redis 将数据库快照保存在名字为dump.rdb的二进制文件中,可以在redis.conf配置文件中修改持久化信息。
    0
    save 900 1 表示在900秒内,至少更新了1条数据。Redis就将数据持久化到硬盘
    save 300 10 表示在300内,至少更新了10条数据,Redis就会触发将数据持久化到硬盘
    save 60 10000 表示60秒内,至少更新了10000条数据,Redis就会触发将数据持久化到硬盘
     

    11.1.1 策略

    1.自动:BGSAVE
    按照配置文件中的条件满足就执行BGSAVE;非阻塞,Redis服务正常接收处理客户端请求;
    Redis会folk()一个新的子进程来创建RDB文件,子进程处理完后会向父进程发送一个信号,通知它处理完毕,父进程用新的dump.rdb替代旧文件。
     
    2.手动:SAVE
    由客户端(redis-cli)发起SAVE命令;阻塞Redis服务,无法响应客户端请求;创建新的dump.rdb替代旧文件。
     

    11.1.2 优点

    1.执行效率高;
    2.恢复大数据集速度较AOF快。
     

    11.1.3 缺点

    1.会丢失最近写入、修改的而未能持久化的数据;
    2.folk过程非常耗时,会造成毫秒级不能响应客户端请求。
     

    11.2 AOF(追加模式、文本重演)

    AOF(Append only file),采用追加的方式保存,默认文件appendonly.aof。记录所有的写操作命令,在服务启动的时候使用这些命令就可以还原数据库。AOF默认关闭,需要在配置文件中手动开启。
    0
     

    11.2.1 写入机制

    说明:AOF机制,添加了一个内存缓冲区(buffer)。
    1.将内容写入缓冲区
    2.当缓冲区被填满、或者用户手动执行fsync、或者系统根据指定的写入磁盘策略自动调用fdatasync命令,才将缓冲区里的内容真正写入磁盘里。
    3.在缓冲区里的内容未写入磁盘之前,可能会丢失。
     

    11.2.2 写入磁盘的策略

    appendfsync选项,这个选项的值可以是always、everysec或者no
    0
    Always:服务器每写入一个命令,就调用一次fdatasync,将缓冲区里面的命令写入到硬盘。这种模式下,服务器出现故障,也不会丢失任何已经成功执行的命令数据
    Everysec(默认):服务器每一秒重调用一次fdatasync,将缓冲区里面的命令写入到硬盘。这种模式下,服务器出现故障,最多只丢失一秒钟内的执行的命令数据
    No:服务器不主动调用fdatasync,由操作系统决定何时将缓冲区里面的命令写入到硬盘。这种模式下,服务器遭遇意外停机时,丢失命令的数量是不确定的
    运行速度:always的速度慢,everysec和no都很快
     

    11.2.3 AOF重写机制

    AOF文件过大,合并重复的操作,AOF会使用尽可能少的命令来记录。

    重写过程

    1.folk一个子进程负责重写AOF文件
    2.子进程会创建一个临时文件写入AOF信息
    3.父进程会开辟一个内存缓冲区接收新的写命令
    4.子进程重写完成后,父进程会获得一个信号,将父进程接收到的新的写操作由子进程写入到临时文件中
    5.新文件替代旧文件
    重写的本质:就是将操作同一个键的命令,合并。从而减小AOF文件的体积
    0
     

    AOF重写触发机制

    1.手动:客户端向服务器发送BGREWRITEAOF命令
    2.自动:配置文件中的选项,自动执行BGREWRITEAOF命令
     
    0
    auto-aof-rewrite-min-size ,
    触发AOF重写所需的最小体积:只要在AOF文件的体积大于等于size时,才会考虑是否需要进行AOF重写,这个选项用于避免对体积过小的AOF文件进行重写
    auto-aof-rewrite-percentage
    指定触发重写所需的AOF文件体积百分比:当AOF文件的体积大于auto-aof-rewrite-min-size指定的体积,并且超过上一次重写之后的AOF文件体积的percent %时,就会触发AOF重写。(如果服务器刚刚启动不久,还没有进行过AOF重写,那么使用服务器启动时载入的AOF文件的体积来作为基准值)。将这个值设置为0表示关闭自动AOF重写。
     

    11.2.4 优点

    写入机制:默认Everysec每秒执行,性能很好不阻塞服务,最多丢失一秒的数据;
    重写机制:优化AOF文件,如果误操作了(FLUSHALL等),只要AOF未被重写,停止服务移除AOF文件尾部FLUSHALL命令,重启Redis,可以将数据集恢复到FLUSHALL 执行之前的状态。
     

    11.2.5 缺点

    1.相同数据集,AOF文件体积较RDB大了很多;
    2.恢复数据库速度较RDB慢(文本,命令重演)。
     
     
    作者:ki16
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    SQL Server 附加数据库,报只读文件,无权修改其中某些文件
    NLog.config 配置
    系统架构设计师论文可靠性设计
    二、软件设计原则
    JavaScript 判断数组是否含有重复值
    mysql 添加索引 mysql 如何创建和删除索引
    利用pandas,BytesIO,zipfile打包csv文件,生成压缩文件
    不良人mysql索引
    转mysql数据库允许空值索引问题
    多线程中ThreadPoolExecutor.map()中传递多个参数
  • 原文地址:https://www.cnblogs.com/gaojinshun/p/15423790.html
Copyright © 2020-2023  润新知