zoukankan      html  css  js  c++  java
  • Redis入门



    最近想优化社团的品牌活动----一个在线答题系统,峰值在400人左右,所以入门Redis来优化


    1. 什么是redis?

    redis是基于内存来储存非关系型数据的键值对数据库。支持数据的持久化(重启加载)与多数据类型(Stirng、Hash、Set、List 、Zset)





    2. 为什么要用redis

    高并发:我们知道内存速度远高于硬盘(一般差3个数量级),redis做热点数据的操作,并且配合基于硬盘的数据库,可以在内存中将热点数据分流,不用每次经过硬盘数据库

    高可用:redis可以实现集群与分布式

    原子性:所有操作都是原子性,因为采用单线程处理,无需考虑并发

    可过期:最让我眼前一亮的是,可过期,和自动删除,但属于惰性删除和随机


    redis是以键值对来存储数据的,虽然Java也有对应的key-value数据结构(map集合),但如果用java的那么数据的过期时间机制需要我们自己实现,而且java的集合是在本地保存的,在多个服务器上无法保持一致性。而且redis可以是数据的持久化,并重返回内存,提供了5大数据类型,这无疑比java的集合要好很多


    特点

    C语言编写,基于内存操作,速度快

    单线程任务机制进行工作,多线程同步

    所有操作是原子性的,使用了队列,支持事务

    单个key存入512M大小,key一定是字符串


    应用

    热点数据加速查询(热点新闻,商品)

    即时信息查询(排行榜,在线人数,访问统计,点赞,浏览次数)

    任务队列(秒杀,抢购)

    时效性信息控制(手机验证码,限时优惠活动,登录次数)

    分布式数据共享(Session分离,Token管理)

    分布式锁、集群





    3 安装与启动

    redis官网只有Linux版本,目前最新稳定版到5.0,而Windows版已经没有更新(最近发布在16年),所以这里安装Linux版本 redis官网下载传送门


    官网有安装编译介绍,对着命令行打就对了,这里做简单提示

    //下载redis压缩包
    $ wget http://download.redis.io/releases/redis-5.0.7.tar.gz
    
    //解压下载的包
    $ tar xzf redis-5.0.7.tar.gz
    
    //进入解压的包
    $ cd redis-5.0.7
    
    //编译
    $ make
    
    //运行redis服务
    $ ./redis-server
    
    //打开客户端
    $ ./redis-cli
    




    4. Redis的配置文件(redis.conf)

    • daemonize no:建议修改为守护进程
    • port 6379
    • bind 127.0.0.1:注释掉才能外部机器访问
    • loglevel notice:日志记录级别
    • database 16:默认16个库
    • save :多少次更新操作就将数据同步到数据文件,可以多个条件配合(持久化机制)
      • save 900 1
      • save 300 10
      • save 60 10000
    • rdbcompression yes:本地存储压缩
    • dbfilename dump.rdb:持久化文件名字
    • dir ./:持久化文件存储地址
    • masterauth <master-password>:主从复制的密码
    • requirepass :登录密码,默认注释掉,没有密码
    • maxclients 0:同一时间最大客户端连接数,默认无限制
    • timeout:300 空闲客户端最大时长

    启动服务端

    ./redis-server ./redis.conf
    

    远程访问

    redis-cli -h IP地址 -p 端口号 -a 密码
    

    关闭

    客户端运行shutdown
    




    5. 通用命令

    keys pattern ( * 任意数量的任意字符,?一个任意字符,[]一个指定字符)
    type key 返回类型
    del keys 返回影响条数
    exists keys 返回存在的条数
    
    
    expire key seconds 设置过期时间
    pexpire key milliseconds 设置毫秒过期时间
    expireat key timestamp 设置过期时间戳
    ttl key 查看过期时间:-1永久,-2过期
    pttl key 查看过期时间:返回的是毫秒
    persist key:移除过期时间,永久保持
    
    
    random key 随机获取一个key
    rename key 改名(若改名存在的key名,则覆盖)
    renamenx 不存在才改名
    move key 移动key到指定数据库
    move key 数据库名称  将当前key移动另个库
    sort [desc limit pattern]针对集合排序不对原数据修改
    
    
    select index 切换数据库
    flushdb 清空当前数据库
    flushall 清空所有数据库
    dbsize  key数量
    
    
    echo message  输出到控制台日志
    ping  测试连通
    quit
    help 命令名称
    help @组名
    clear 清屏
    

    事例

    set user:1 a
    set user:2 b
    keys user:?    将二者列出,*统配符,?单个通配符
    




    6. Key命名规范

    • key太长,降低查找效率、不短,可读性降低
    • 同一命名模式:表名:主键名:主键值:字段名
      • user : id : 01 : username ----- howl
      • user : id : 01 : password ----- 123456




    7. 数据类型

    key最大512M,建议不超过1025字节


    1. String

    mset / mget 	 批量读写,缺点数据量太多时候还是要切小点来批量处理
    
    
    set key value 重复设置是覆盖,String可以不管类型覆盖
    setnx name key 	键不存则新建,存在不覆盖返回0  // 重点分布式锁的命令,面试题,为数据库id提供生成策略,保证唯一
    setex/psetex key seconds value // 重新设置会被清除覆盖
    
    
    get key 获取值,不存在返回nil(查询非字符串报错)
    getrange start end  截取,不包括尾
    getset key value 设置指定key值,并返回旧key值;若key不存在,设置set key后返回nil
    
    
    incr key	 自增,返回增后的值;key不存在会先set为0,再自增,返回1
    decr key 	自减,返回减后的值;key不存在会先set为0,再自减,返回-1
    incrby key num 	自增/减num
    decrby key num 	自增/减num
    incrbyfloat key 1.5 可以小数,前面的不行
    
    
    strlen key 返回字符串长度
    getbit key offset  偏移量
    append key value  追加,返回总长度,没有就新键
    
    
    视为数值操作的最大值
    可以利用这个限制登录次数:eg一开始就设置为2^63-10,登录一次加10,到第10次就报错
    long:8字节,2^63
    

    应用场景:

    • 计数器统计(投票,粉丝数)
    • 保存单个字符串或JSON
    • 二进制安全(存文件、图片、序列化对象)


    2. Hash

    存取键值对,一个Sting类型的 field 和 value 的映射表,是个K/V形式的集合,特别适合存储对象。

    一个hash可以存2^32 -1 个数据(40亿),而且占用内存少。笔者称field 为字段,value为值

    hash类型下的value只能存字符串,不能存储其他类型了, 即不能嵌套

    形式: user:1(key)  (hash)id:1 name:howl age:20
    
    
    hset key field value
    hsernx key filed value
    hmset key field value field,value
    
    
    (这里获取的是值)
    hget key field
    hmget key field field
    hgetall key 取出所有内容,包括字段与值(先列字段,再列值)
    
    
    (这里获取的是字段)
    hkeys key  取出全部字段
    hvals key  取出全部值
    hlen key 多少个字段
    hdel key field[field] 删除某个字段
    
    
    hincrby user:1 age 10
    hincrbyfloat user:1 age 10
    hexists key field  是否存在字段
    

    应用场景:

    • 存储用户对象信息
    • 如果用String存对象,如果用json,就要转换成bean对象,且修改字段要排队。比如连续修改同一个字段,要将json取出修改完存进去,然后再取出来修改存进去(CAS问题)。而Hash类型可以直接修改字段。;第二种:字段分开存,即有多少个字段,存多少条记录,条数过多内存浪费
    • 抢购、激活码等


    3. List

    模拟栈和队列,类似于Java中的LinkedList类型,是简单的字符串列表(每个key里面可以存字符串列表),可以从头部或尾部添加元素。列表可以包含2^32-1个元素(40亿了),注重进出顺序

    lpush key value1 value2  从左边添加元素,头插法咯
    rpush key value1 value2  从右边添加元素
    lpushx key value  从已存在的列表中插入值,若列表不存在报错
    
    
    lpop key 弹出左侧第一个元素
    rpop key 弹出右侧第一个元素
    
    
    llen key  获取列表长度
    lindex key index  通过索引获取列表中的元素
    lrange key start stop  范围获取,-1标识最后一个,-2倒数第二个
    
    
    lset key index value  通过索引设置列表元素的值
    lrem key count value  count是删除几个,可以重复的
    linsert ket before/after world value  在该元素前后插入
    blpop/brpop key timeout 弹出元素,没有就会阻塞直到等待超时或发现可弹出元素位置(任务队列)
    
    
    rpoplpush source destination  将source右弹出的元素加入destination的左侧
    rpoplpush a1 a1  可以实现循环,即右侧的元素放到左侧
    

    应用场景:

    • 对数据量大的集合集合数据测(列表数据显示(有顺序的):关注列表,粉丝列表,留言评论?分页,热点新闻(top5))
    • 消息队列,而且可以确保那样还需通过ORDER BY 进行排序,订单下单流程,注册短信,邮箱等功能。需要两个队列,还是一个就可以? 一个添加消息,一个消费消息,使用rpoplpush命令。然后举例物流,从这两个列表,可以查询出快递到哪,还有多少任务未完成


    4.Set

    存取速度快,成员是唯一的,是String类型的无序集合。底层通过哈希实现,所以添加删除查找都是O(1),使用inset和hashtable实现。

    sadd key memeber1 member2  向集合添加成员(重复添加返回0)
    
    
    smembers key  获取集合的所有成员
    srandmember key[count] 返回集合中的随机(抽奖),原集合内容不变
    spop key [count] 随机弹出数据
    
    
    scard key  获取集合成员数
    sismember key member  判断 memeber 元素是否在存在
    
    
    srem key member1 member2  删除集合成员
    spop key[count]  随机弹出集合元素
    smove source destioantion member  将member元素从source移到destinatio中
    
    
    (集合运算)
    sdiff key1 key  返回差集(从key1看)
    sinter key1 key2  返回交集
    sunion key1 key2  返回并集
    sdiffstore destinatio key[key]  将集合运算结果存储到指定集合
    

    应用场景:

    • 共同关注,共同喜好(集合运算等)
    • 随机信息检索,歌单推荐,新闻推荐
    • 黑白名单
    • 唯一性,可用于访问网站的独立IP
      • 访问量,String即可
      • 独立访客,Set记录不同的cookie数量
      • 独立IP,Set记录不同IP


    5.ZSet

    String类型的不允许重复,但有序的集合。因为每个元素会关联一个double类型的分数,利用这个分数来为集合排序,而分数是可以重复的

    这里注意:重复添加返回0,说明数据没有新添加,但权值是会改变的
    zadd key score member [score member]  添加集合元素
    
    
    zrank key member  返回指定成员的索引(排序下标)
    zrange key start stop [withscore]  返回区间内的成员(低到高),后面带上了权值
    zrevrange key start stop [withscore]  通过索引区间返回有序集合指定区间内的成员(高到低)
    
    
    zrangebyscore key min max [withscores] [limit 0 3]
    zrevrangebyscore key min max [withscores] [limit 0 3]
    zremrangebyrank key start stop  移除指定排名区间所有成员
    zremrangebyscore key min max  移除给定分数区间的所有成员
    zrem key member[member]  移除集合中的成员
    
    
    zcard key  获取有序集合的成员数量
    zcount key min max  计算在有序集合中指定分数区的成员数
    
    
    zinterstore destionation numkeys key key 集合操作
    zincrby key increment member  权值增减(可以作为排行榜的得分来排序)
    

    应用场景:

    • 排行榜
      • 将发表时间作为score来存储
      • 带权的队列(扩展列表完全按序的功能)
      • 涨幅跌幅




    8. Java连接Redis

    这里使用Jedis来连接,关系就像jdbc之于mysql,笔者使用pom.xml导入依赖

    Jedis的方法名和redis的一模一样,所以熟悉redis命令即可熟悉使用Jedis

    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.2.0</version>
    </dependency>
    
    public static void main(String[] args) {
    
        // 配置信息,建议放外部文件,这里为了演示
        int port = 6379;
        String password = "123456";
        String host = "47.56.143.47";
    
        // 连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10); // 连接数
        poolConfig.setMaxIdle(5); // 空闲数
    
        // 获取连接,获取了连接还需要验证密码
        JedisPool pool = new JedisPool(poolConfig, host, port);
        Jedis jedis = pool.getResource();
        jedis.auth(password);
    
        // 二进制安全,String
        jedis.set("中文", "中文");
        System.out.println(jedis.get("中文"));
        
        // List
        jedis.lpush("list","list1");
        jedis.rpush("list","list2");
        List<String> list = jedis.lrange("list",0,-1);
        for(String value : list){
            System.out.println(value);
        }
    
        // Hash
        jedis.hset("hset","field1","value1");
        jedis.hset("hset","field2","value2");
        Map<String,String> map = jedis.hgetAll("hset");
        for(String key : map.keySet()){
            System.out.println(map.get(key));
        }
    
        // 关闭
        jedis.close();
    }
    




    9. Redis Manager

    Redis之于Redis Manager 就像MySQL之于Navicat,是可视化的Redis连接管理工具。有个坑,不知道大家有没有遇到,输入命令行键盘上的两个回车作用不一样,大回车键是执行命令,右下角的回车是换行功能。

    界面操作简单,一个个点击操作下就知道如何使用了



  • 相关阅读:
    docker---基本操作
    one_day_one_linuxCmd---netstat命令
    docker---Dockerfile编写
    one_day_one_linuxCmd---sz命令
    one_day_one_linuxCmd---scp命令
    同义英语词汇整理
    网络实习——校园网络设计方案
    实现 FTP 客户端和服务器程序所调用的系统函数
    2020年上半年总结
    单片机的串行总线拓展技术
  • 原文地址:https://www.cnblogs.com/Howlet/p/12669676.html
Copyright © 2011-2022 走看看