Redis入门

Redis入门

  • SQL与NOSQL
  • Redis是什么
    • Redis服务端安装(Linux)
    • Redis的使用
      • redis-cli命令
      • redis clients推荐(Java)
    • Redis的数据类型及使用
      • String类型
        • String类型常用的操作命令
        • String的应用场景
      • Hash
        • Hash的基本介绍
        • Hash的操作命令
        • Hash的应用场景
      • List
        • List的操作命令
        • List应用场景
      • Set
        • Set的操作命令
        • Set的使用场景
      • ZSet
        • ZSet的操作命令
        • ZSet的应用场景
      • Geo Spatial
        • Geo的操作命令
      • HyperLogLogs
        • HyperLogLogs的操作命令
        • HyperLogLogs应用场景

SQL与NOSQL

SQL:指关系型数据库;1.基于行存储的二维结构化数据,2.有固定化模式,必须定义好表和字段结构后才能添加数据。3.表与表之间存在关联,4.有SQL语法。5.支持事务ACID,原子性、一致性、隔离性、持久性。
缺点:不支持动态的扩容缩容、表的结构难以修改,存储的数据格式不灵活。在高并发的场景下,磁盘读写压力大。
NOSQL:泛指非关系型数据库;1.非结构化的数据,2.数据与数据没有关联,3.没有事务性,遵循BASE理论,即最终一致性,4.海量数据存储、支持高并发读写,5.支持分布式:数据分片、扩缩容简单。
现在市面上常用的NOSQL数据库有以下几种类型:

  • KV存储(redis)
  • 文档存储(MongoDB)
  • 列存储(HBase)
  • 图存储(Graph、Neo4j)
  • 对象存储
  • XML存储
  • ......
  • Redis是什么

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 带范围查询的有序集合(sorted sets), bitmaps, hyperloglogs ,带半径的地理空间索引查询和流(geospatial)。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

    Redis服务端安装(Linux)

    1.下载redis安装包
    wget https://download.redis.io/releases/redis-5.0.5.tar.gz
    2.解压缩
    tar -zxvf redis-5.0.5.tar.gz
    3.安装redis编译环境,因为redis是用c语言开发的,需要安装gcc依赖
    yum install gcc
    可以通过gcc -v查看是否安装。(需要注意的是redis.6支持多线程,但是需要gcc版本大于4.9)
    在这里插入图片描述
    4.编译安装

    cd redis-5.0.5
    make MALLOC=libc
    

    将redis-5.0.5/src目录下的二进制文件安装到/usr/local/bin

    cd src
    make install
    

    5.修改配置文件redis.conf

  • 是否后台启动:daemonize no 改为 daemonize yes
  • 在这里插入图片描述

  • 将 `bind 127.0.0.1` 注释或者改为 `bind 0.0.0.0`,否则将只能在本机被访问
  • 在这里插入图片描述

  • 如果连接时需要密码访问,取消requirepass的注释。改为 requirepass [password]
  • 在这里插入图片描述
    6.使用指定配置文件启动Redis(当想要运行多个redis时,只需要通过运行redis-server指定不同的conf文件即可)
    /usr/local/soft/redis-5.0.5/src/redis-server /usr/local/soft/redis-5.0.5/redis.conf
    如图即为运行成功,其默认端口号为6379
    在这里插入图片描述
    7.通过./redis-cli 可以进入默认的redis客户端(在src目录下)
    8.停止redis命令:shutdown(在客户端中)或通过kill -9 port

    Redis的使用

    ps:在部分redis可视化管理工具中,连接redis数据库成功后,会出现一串数据库。但是,redis与关系型数据库不同,这一串数据库并没有进行完全的隔离。所以,不需要对相关的业务进行指定数据库。

    redis-cli命令

    1.flushall清空所有数据库
    2.flushdb 清空当前数据库
    3.select [number]跳转到相应编号的数据库
    …推荐使用Redis 命令参考进行详细的命令查阅

    redis clients推荐(Java)

    1.Jedis
    一款轻量级的针对Redis的Java客户端。需要注意,在多个线程使用同一个Jedis链接去操作数据的时候,有可能出现数据干扰的情况。此时可以通过每个线程创建一个新的Jedis链接或通过数据库连接池进行处理。
    Maven引入方式:

    <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>4.2.3</version>
            </dependency>
    

    使用:

    Jedis jedis = new Jedis(url, port);
    

    连接池的使用

    JedisPoolConfig config=new JedisPoolConfig();
    //1.设置连接池的基本配置
    config.setMaxTotal(10);
    config.setMaxIdle(1);
    //2.设置连接池目标数据库
    JedisPool jedisPool = new JedisPool(config, url, port);
    //3.调用连接
    Jedis resource = jedisPool.getResource();
    //4.关闭,归还到连接池中
    resource.close();
    

    2.lettuce
    可扩展的线程安全的客户端,支持异步模式。如果避免阻塞和事务操作,如BLPOP和MULTI/EXEC,多个线程就可以共享一个连接。lettuce 底层基于 Netty,支持高级的 Redis 特性,比如哨兵,集群,管道,自动重新连接和Redis数据模型。
    在spring-boot 2.0版本中,Lettuce作为默认的Redis访问客户端,(2.0之前是Jedis)可以通过下面的方式引入:

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>
    

    同步调用方法

    //创建客户端
            RedisClient client=RedisClient.create("redis://192.168.2.128:6379");
            //线程安全的长连接,连接丢失时会自动重连
            StatefulRedisConnection<String, String> connect = client.connect();
            //获取同步执行命令,默认超时时间为60s
            RedisCommands<String, String> sync = connect.sync();
            sync.set("key","value");
            System.out.println(sync.get("key"));
            //关闭连接
            connect.close();
            //关闭客户端
            client.shutdown();
    

    异步调用与同步不同的是,其调用方法用RedisFuture进行了封装:

    //创建客户端
            RedisClient client=RedisClient.create("redis://192.168.2.128:6379");
            //线程安全的长连接,连接丢失时会自动重连
            StatefulRedisConnection<String, String> connect = client.connect();
            RedisAsyncCommands<String, String> async = connect.async();
            async.set("Lettuce", "async773");
            RedisFuture<String> future = async.get("Lettuce");
            String s = null;
            try {
                s = future.get(60, TimeUnit.SECONDS);
            } catch (InterruptedException | ExecutionException | TimeoutException e) {
                e.printStackTrace();
            }
            System.out.println("--"+ s);
    
    

    3.Redisson
    在Redis 的基础上实现的 Java 驻内存数据网格,可以为Java提供分布式、可扩展的数据结构,以及提供很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列等。

            <dependency>
               <groupId>org.redisson</groupId>
               <artifactId>redisson</artifactId>
               <version>3.5.4</version>
           </dependency>
    
    private static RedissonClient redissonClient;
    
       static {
           Config config=new Config();
           config.useSingleServer().setAddress("redis://127.0.0.1:6379");
           redissonClient= Redisson.create(config);
       }
    
       public static void main(String[] args) throws InterruptedException {
           RLock rLock=redissonClient.getLock("updateAccount");
           // 最多等待100秒、上锁10s以后自动解锁
           if(rLock.tryLock(100,10, TimeUnit.SECONDS)){
               System.out.println("获取锁成功");
           }
           Thread.sleep(20000);
           rLock.unlock();
    
           redissonClient.shutdown();
       }
    

    Redis的数据类型及使用

    字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 带范围查询的有序集合(zsets), bitmaps(位图), hyperloglogs(用来做基数统计的算法) ,带半径的地理空间索引查询和流(geospatial)

    String类型

    1.String类型可以存储的数据类型包括:String、INT、Float。

    String类型常用的操作命令

    1.对String数据类型的操作

    set key value [过期时间:EX secends/PX milliseconds] [NX (当已经有当前key时,
    val不可以被设置,set不成功)/XX(只有key存在时,set才能成功)]
    mset key value key value ......#批量设置
    mget key key.....#批量获取(程序返回list)
    strlen key #获取value的长度
    append key value #在key原有的val上追加value
    getrange key [start] [end] #返回value的start下标到end下标的数据,end=-1表示获取value
    

    2.对INT数据类型的操作

    incr key #对value进行递增
    incrby key [step]  #对value按照步数step进行递增
    decr key #对value进行递减
    decrby key [step]#对value按照步数step进行递减
    

    3.对Fload类型的操作

    set key value
    incrbyfloat key [step]
    

    4.位操作(String类型在Redis里是一个8位二进制进行存储的,可以通过位操作改变数据)

    setbit key index bitval #将key的value的二进制数组中下标为index的数据改为bitval(1/0)
    getbit key index #获取value二进制数组中下标为index的bitval
    getpos key bitval #获取value中第一个bitval(1/0)的下标
    bitcount key #统计value中1的个数
    BITOP AND resultKEY KEY1 ... KEYN #对一个或多个key求逻辑与,并将结果保存到reusultKEY
    BITOP OR resultKEY KEY1 ... KEYN #对一个或多个key求逻辑或,并将结果保存到reusultKEY
    BITOP XOR resultKEY KEY1 ... KEYN #对一个或多个key求逻辑异或,并将结果保存到reusultKEY
    BITOP NOT resultKEY KEY1 ... KEYN #对一个或多个key求逻辑非,并将结果保存到reusultKEY
    
    String的应用场景

    1.缓存
    2.分布式session
    3.set NX EX 分布式锁
    4.incr 全局ID/计数器/限流
    5.位操作 统计

    Hash

    1.String可以通过key的分层实现对一张表的数据存储:在redis里,我们可以通过:对key进行分层。
    当然,这种做法的弊端也很明显,当表的数据结构过于复杂时,String类型会成为一个复杂的串。

    set key1:key2:key3 value
    set key1:key5:key6 value
    keys key1* #=>输出key1:key2:key3;key1:key5:key6
    keys key1:key2* #=>输出key1:key2:key3
    
    Hash的基本介绍

    Hash类型的结构:
    在这里插入图片描述

        Hash相较于String类型,更加节省空间,同时通过一个key存储多个键值对的方式,减少了key的创建量,从而减少了key的命名冲突,在读取时,也可以通过一个key获取到一系列的相关数据,避免反复请求,减少了资源消耗
        当然,由于无法单独对Field进行精细化控制(如设置过期时间等),同时也Hash无法进行bit操作。
        同时,由于Redis集群式通过KEY进行取模从而决定将它分布到不同Redis节点上,以达到平衡存储压力的。而Hash类型只能共用一个KEY,无法进行分散存储,当一个Hash过大时,会造成单个Redis节点存储压力过大。而String类型就没有这方面的顾虑,所以,在某些场景下,String类型依旧时不可替代的。

    Hash的操作命令
    hset key field value #设置值
    hmset key field1 val1 ... fieldN valN #一次性设置多个
    hget key field1#取值
    hmget key field1 ... fieldN #取多个值
    hkeys key #输出key下的所有field
    hvals key#输出key下的所有value
    hgetall key#输出key下的所有field及value
    hdel key field #删除key下的某个元素
    hlen key #返回key下的元素个数
    hexists key field #返回1,表示key下有field这个键值对
    hincrby key field1 step #对整型内容进行递增(hash未提供递减关键字,可以将step设为负数实现)
    hincrbyfloat  key field1 step #对浮点型内容进行递增
    

    == 在这里我们需要注意到,Redis直接删除集合类型大KEY时,一般每秒可清理100w到数百w的元素;如果数千w个元素的大KEY进行删除时,会导致Redis阻塞10s以上,使集群认为Redis故障,导致故障切换或者应用程序雪崩。(Redis是单线程的,耗时过大的命令会导致其他命令被阻塞,引起应用程序雪崩或Redis集群发生故障切换)。==

    Hash的应用场景

    1.存储一张表、一个复杂的对象
    2.购物车功能

    List

    Redis里的List,本质是一个双向链表,有序,左边是列表头,右边是列表尾,顺序是从左到右。因此,可以作为队列或者栈使用。一个List可以容纳 2 32 − 1 2^{32}-1 2321的元素。

    List的操作命令
    lpush key val ...#在队列左侧添加一个或多个元素
    rpush key val ...#在队列右侧添加一个或多个元素
    lpop key #从队列左侧弹出一个元素
    rpop key #从队列右侧弹出一个元素
    lindex key  index #通过下标获取队列中的对应元素(从左侧)
    lrange key  start end #获取一定范围里对应的元素
    blpop key timeout #弹出一个元素,有阻塞性质,如果没有数据,会一直阻塞等待,直timeout时间
    brpop key timeout #右侧弹出,同上,这两种用法常用于消息队列
    lrem key [count] value #移除 count>0,从左向右,移除与value相等的元素,数量为count
    #count<0,从右向左,移除与value相等的元素,数量为count的绝对值
    #count=0,移除表中所有与value相等的值
    
    List应用场景

    1.消息队列
    2.用户时间线

    Set

    Set,一个无序的字符串集合,存储元素的容量与List一样

    Set的操作命令
    sadd key val1 ... valN #添加元素
    smembers key #获取集合里所有元素
    scard key#获取集合中元素的数量
    srandmember key [count]#从集合中随机返回一个元素,如果带数量,则返回指定数量的元素
    #这种返回,不会从集合中将元素删掉
    spop key [count]#返回元素并删除
    srem key val1 ... valN #直接移除指定元素
    sismember key val # 判断集合中是否存在元素val
    ############集合之间的操作###################
    sdiff key1 key2 #获取差集,只在第一个集合中有的
    sinter key1 key2 #获取交集
    sunion key1 key2 #获取并集(合并去重)
    sdiffstroe desSet key1...keyN #将集合之间的差集存储到指定集合中
    
    Set的使用场景

    1.抽奖
    2.点赞、签到、打卡一类的操作及统计
    3.商品标签
    4.电商的商品筛选
    5.用户关注模型

    ZSet

    ZSet,有序集合,每一个元素都有一个分值,分值越小越靠前,当分值相同时,通过元素的ASCII码进行排序

    ZSet的操作命令
    zadd key score1 val1 ... scoreN valN #添加元素,分值要写在元素的前面
    zrange key start end withscores #获取范围内的元素,并显示分值
    zrevrange key start end withscores#获取范围内的元素,分值大的在前面
    zrangebyscore key min max #获取分值范围内的元素
    zrem key val1 ... valN #移除指定元素
    zcard key #获取元素数量
    zincrby key score valn #增加元素的分值 
    zrank key valN #获取指定元素的下标
    zscore key valN #获取元素的分值
    
    ZSet的应用场景

    1.排行榜

    Geo Spatial

    用来保存地理位置信息的数据类型,同时,Redis提供了一系列地理位置的计算方法,方便相关功能的实现。

    Geo的操作命令
    geoadd key [longitude] [latitude] valN ...#添加key中的经度 纬度 元素
    geopos key valN #获取对应元素的经纬度
    geodist key val1 val2 [unit]#计算两个元素的距离,unit表示单位 可以用m/km或mi(英里)/ft(英尺)
    georadius key [longtude] [latitude] num [unit] #key中距离输入的及维度指定距离num内的元素
    georadiusbymember key valN num [unit]#距离valN元素位置不超过num距离的元素
    

    HyperLogLogs

    提供了一种基于基数的统计方法,可以用很少的内存统计很大的基数(不同元素),当然,代价是会产生一定的误差

    HyperLogLogs的操作命令
    pfadd key val1 ...valN
    pfcount key #元素数量
    pfmerge resultkey key keyN #合并多个key并保存到resultkey中
    
    HyperLogLogs应用场景

    1.网站用户访问量统计

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值