Redis的基本使用

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 1.Redis简介(1)什么是Redis①Redis是一个基于内存的key-value结构数据库②基于内存存储,读写性能高③适合存储热点数据(热点商品、资讯、新闻)④Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件⑤它存储的value类型比较丰富,也被称为结构化的NoSql数据库。NoSql,不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。




1.Redis简介


(1)什么是Redis

①Redis是一个基于内存的key-value结构数据库

②基于内存存储,读写性能高

③适合存储热点数据(热点商品、资讯、新闻)

④Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件

⑤它存储的value类型比较丰富,也被称为结构化的NoSql数据库。NoSql,不仅仅是SQL,泛指非关系型数据库。NoSql数据库

并不是要取代关系型数据库,而是关系型数据库的补充。


(2)Redis应用场景

①缓存

②任务队列

③消息队列

④分布式锁


(3)Redis默认有16个数据库,类似数组下标从0开始,初始默认用0号库

①使用命令 select 来切换数据库。如select 8

②统一密码管理,所有库使用统一密码

③dbsize :查看当前数据库的key的数量

④flushdb:清空当前库

⑤通杀全部库


(4)Redis是单线程+多路IO复用技术

多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)

与Memcache的三点不同:支持多数据类型,支持持久化,单线程+多路复用


2.Redis常用操作命令


2.1 键(key)


①keys * 查看当前库所有key

②exists key 判断某个key是否存在

③type key 查看你的key是什么类型

④del key 删除指定的key数据

⑤unlink key 根据value选择非阻塞删除(仅将key从keyspace元数据中删除,真正的删除会在后续异步操作)

⑥expire key 时间(时间单位:秒,为给定的key设置过期时间

⑦ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已过期


2.2 字符串(String)


(1)String是Redis最基本的类型,可以理解成与Memcached一模一样的类型,一个key对应一个value


(2)String类型是二进制安全的,意味着Redis的String可以包含任何数据。比如jpg图片或者序列化的对象


(3)String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M


(4)String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS).是可以修改的字符串,内部结构实现上类似于

Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配


①set key value //设置指定key的值

补充:mset key1 value1 key2 value2 … // 同时设置一个或多个 key-value

②get key // 获取指定key的值

补充:mget key1 value1 key2 value2 … // 同时获取一个或多个 key-value

③setex key 过期时间 value // 设置指定key的值,并将key的过期时间设为 seconds 秒

④setnx key value // 只有在key不存在时设置 key 的值

补充:msetnx key1 value1 key2 value2 …

//同时设置一个或多个key-value对,当且仅当所有给定key都不存在(原子性,有一个失败则都失败)

⑤strlen key 获得值的长度

⑥incr key 将key中存储的数字值增1,只能对数字值操作,如果为空,新增值为1

⑦decr key 将key中存储的数字值减1

补充:incr key 对存储在指定key的数值执行原子的加1操作

所谓原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会

有任何 context switch(切换到另一个线程)


1.在单线程中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断只能发生于指令之间

2.在多线程中,不能被其他进程(线程)打断的操作就叫原子操作。

Redis单命令的原子性主要得益于Redis的单线程

⑧getrange key 起始位置 结束位置

获得值的范围,类似于java中的subString(这里是 前包,后包)

⑨setrange key 起始位置 value

用value覆写key所存储的字符串值,从<起始位置>开始(索引从0开始)

⑩getset key value //以旧换新,设置了新值的同时获得旧值


2.3 列表list操作命令


Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部或者尾部。List的数据结构为快速链表quickList,首先在列表元素比较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也就是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较大时才会改成quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间。Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。

①lpush/rpush key value1 value2 … // 将一个或多个值插入到列表头部/尾部

例如:lpush mylist a b c

②lrange key start stop //按照索引下标获得元素(从左到右)

例如:lrange mylist 0 -1 // 0 -1表示获取所有

③lpop/rpop key // 从左边/右边吐出一个值(值在键在,值光键亡)

④llen key // 获取列表长度

⑤brpop key1 key2 … timeout // 移出并获取列表的最后一个元素,或发现可弹出元素为止

//timeout 超时时间;列表没有元素,就会一直阻塞直到超时

⑥lindex key index 按照索引下标获得元素(从左到右)


2.4 集合set操作命令


Redis的set 是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。它的底层其实是一个

value为null的hash表,所以添加,删除,查找的复杂度都是O(1)

①sadd key member1 member2 … //向集合中添加一个或多个成员

②smembers key // 返回集合中的所有成员

③sismember key value // 判断集合key是否为含有该value值,有1,没有0

④scard key // 返回该集合的元素个数

⑤sinter key1 key2 … // 返回给定所有集合的交集

⑤sunion key1 key2 … // 返回所有给定集合的并集

⑥sdiff key1 key2 … // 返回给定所有集合的差集(key1中有的,不包含key2中的)

⑦srem key member1 member2 … // 移除集合中一个或多个成员

⑧smove   value // 把集合中一个值从一个集合移动到另一个集合

⑨spop key // 随机从该集合中吐出一个值


2.5 有序集合Zset(sorted set)操作命令


Redis sorted set 有序集合是string类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score)。

redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。

①zadd key score1 member1 score2 member2 … // 向有序集合中添加一个或多个成员,或者更新已存在成员的分数

②zrange key start stop [WITHSCORS] // 通过索引区间返回有序集合中指定区间内的成员(withscors可以带分数一起返回)

③zincrby key increment member // 有序集合中对指定成员的分数加上增量 increment

④zrem key member [member …] // 移除有序集合中的一个或多个成员

zset底层使用了两个数据结构:

(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到对应的score值。

(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表


2.6 哈希 hash 操作命令


Redis hash是一个String类型的filed和value的映射表,hash特别适合用于存储对象。hash类型对应的数据结构是两种:

ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable

①hset key filed value // 将哈希表key中的字段field的值设为value

②hget key field // 获取哈希表中指定字段的值

③hdel key field // 删除存储在哈希表中的指定字段

④hkeys key // 获取哈希表中所有字段

⑤hvals key // 获取哈希表中所有值

⑥hgetall key // 获取在哈希表中指定key的所有字段和值


fe377ddc237c44d68b1870970cf84f84.png


2.7 通用命令


①KEYS pattern // 查找所有符合给定模式(pattern的)key

例如: keys *

②EXISTS key // 检查给定 key 是否存在

③TYPE key // 返回key所存储的值的类型

例如:type myset

④TTL key // 返回给定 key 的剩余生存时间,以秒为单位

例如:ttl name

⑤DEL key // 该命令用于在key存在时删除key


3.Redis的新数据类型


3.1 Bitmaps


(1)简介

现代计算机采用二进制(位)作为信息的基础单位,1个字节等于8位,例如“abc”字符串是由3个字节组成,但实际在计算机

存储时将其用二进制表示,“abc”分别对应的ASCII码分别是97、98、99,对应的二进制分别是01100001、01100010和

01100011。合理的使用操作位能够有效地提高内存使用率和开发效率。Redis提供了Bitmaps这个“数据类型”可以实现对

位的操作

①Bitmaps本身不是一种数据类型,它实际上就是字符串(key-value),但是它可以对字符串的位进行操作

②Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个

以位为单位的数组,数组的每个单位只能存储0和1,数组的下标在Bitmaps中叫做偏移量。


(2)格式

①setbit key offset value // 设置Bitmaps中某个偏移量的值(0或1),偏移量offset从0开始

②getbit key offset // 获取Bitmaps中某个偏移量的值

③bitcount key start end // 统计字符串从start字节到end字节比特值为1的数量


4.Redis的配置文件介绍


4.1 ###Units单位###


配置大小单位,开头定义了一些基本的度量单位,只支持 bytes,不支持 bit ,大小写不敏感


4.2 ###INCLUDES包含###


类似于jsp中的 include,多实例的情况可以把公用的配置文件提取出来


4.3 ###网络相关配置


(1)bind

默认情况下 bind = 127.0.0.1 只能接受本机的访问请求,不写的情况下,无限制接受任何ip地址的访问

(2)protected-mode

如果开启了protected-mode,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的响应

(将本机访问保护模式设置no)

(3)Port:端口号,默认 6379

(4)tcp-backlog

①设置tcp的backlog,backlog其实是一个连接队列,backlog队列总和=未完成三次握手队列 + 已经完成

三次握手队列。

②在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。

注意Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值(128),所以需要确认增大/proc/sys/net/core/somaxconn和/proc/sys/net/ipv4/tcp_max_syn_backlog(128)两个值来达到想要的效果

(5)timeout

一个空闲的客户端维持多少秒会关闭,0表示关闭该功能。即永不关闭。

(6)tcp-keepalive

①对访问客户端的一种心跳检测,每隔n秒检测一次。

②单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60

③如果还活着继续提供服务,不活着就释放连接


4.4 ###GENERAL通用###


(1)daemonize

是否为后台进程,设置为yes。守护进程,后台启动

(2)pidfile

存放pid文件(存放进程号)的位置,每个实例会产生一个不同的pid文件

(3)loglevel

①指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为notice

②四个级别根据使用阶段来选择,生产环境选择notice 或者warning

(4)logfile:设置日志的输出文件路径,默认为空

(5)databases

设定库的数量 默认16,默认使用0号数据库,可以使用SELECT 命令在连接上指定数据库id


4.5. ###SECURITY安全###


(1)设置密码

①默认是没有密码的,设置密码可以把下面的注释打开


906f0ae45b2f4c1e98c759621e084c26.png


②在命令行中设置密码,只是临时的。重启redis服务器,密码就还原了。


6a8e469279e94976b351159bb2f06708.png


4.6 #### LIMITS限制


(1)maxclients

①设置redis同时可以与多少个客户端进行连接

②默认情况下为 10000 个客户端

③如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方

发出“max number of clients reached”以作回应。

(2)maxmemory

①建议必须设置,否则,将内存占满,造成服务器宕机

②设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以

通过maxmemory-policy来指定。

③如果redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么redis则会针对那些

需要申请内存的指令返回错误信息,比如SET、LPUSH等。

④但是对于无内存申请的指令,仍然会正常响应,比如GET等。如果你的redis是主redis(说明你的redis有从redis),

那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的

情况下,才不用考虑这个因素。

(3)maxmemory-policy

①volatile-lru:使用LRU算法移除key,只对设置了过期时间的键;(最近最少使用)

②allkeys-lru:在所有集合key中,使用LRU算法移除key

④volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键

⑤allkeys-random:在所有集合key中,移除随机的key

⑥volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key

⑦noeviction:不进行移除。针对写操作,只是返回错误信息

(4)maxmemory-samples

①设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值,所以你可以设置样本的大小,redis默认

会检查这么多个key并选择其中LRU的那个。

②一般设置3到7的数字,数值越小样本越不准确,但性能消耗越小


5.Redis的发布和订阅


5.1 什么是发布和订阅


(1)Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息

(2)Redis客户端可以订阅任意数量的频道


a278bbd0e77e44a1822a4331c5aa9beb.png


5.2 发布订阅命令行实现


(1)打开一个客户端订阅 channel1

subscribe channel1

(2)打开另一个客户端,给channel1发布消息hello

publish channel1 hello // 返回的1是订阅者数量

(3)打开第一个客户端可以看到发送的消息

注:发布的信息没有持久化,如果在订阅的客户端收不到hello,只能收到订阅后发布的信息


6.在Java中操作Redis


5.1 使用Jedis操作Redis


1)导入相关坐标


<!--   Jedis坐标   -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.1</version>
        </dependency>


(2)相关实例


public class JedisTest {
    @Test
    public void testJedis() {
//        1.获取连接
        Jedis jedis = new Jedis("localhost", 6379);
//        2.执行具体的操作
        jedis.set("username","lisi");
        String value = jedis.get("username");
        System.out.println(value);
//        3.关闭连接
        jedis.close();
    } }


6.2 在Spring Boot项目使用Spring Data Redis操作Redis


Spring Data Redis 中提供了一个高度封装的类:RedisTemplate,针对jedis客户端中大量api进行了归类封装,将同一类型操作

封装为opperation接口,具体分类如下:

①ValueOperations:简单K-V操作

②SetOperations:set类型数据操作

③ZSetOperations:zset类型数据操作

④HashOperations:针对map类型的数据操作

⑤ListOperations:针对list类型的数据操作

(1)导入相关坐标


<!--  Spring Data Redis -->
 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>


(2)Redis相关配置


spring:
# Redis相关配置
  redis:
    host: localhost
    port: 6379
    database: 0 # 默认有16个数据库,操作的是第0号数据库
    jedis:
# Redis连接池配置
      pool:
        max-active: 8 # 最大连接数
        max-wait: 1ms # 连接池最大阻塞等待时间
        max-idle: 14 # 连接池中的最大空闲连接
        min-idle: 0 # 连接池中的最小空闲连接


(3)Redis配置类


@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
//        创建RedisTemplate对象
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
//        设置连接工厂
        template.setConnectionFactory(connectionFactory);
//        创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//        设置key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
//       设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
//        返回
        return template;
    }  }


(3)实例


@SuppressWarnings("all")
@SpringBootTest(classes = SsmMangerApplication.class)
@RunWith(SpringRunner.class)
public class SpringDataRedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    //操作String类型数据
    @Test
    public void testString() {
        redisTemplate.opsForValue().set("city", "beijing");
        Object city = redisTemplate.opsForValue().get("city");
        System.out.println(city);
    }
    //    操作Hash类型数据
    @Test
    public void testHash() {
        HashOperations hashOperations = redisTemplate.opsForHash();
//        存值
        hashOperations.put("002", "name", "xaioming");
        hashOperations.put("002", "age", "20");
        hashOperations.put("002", "address", "bj");
//        取值
        String age = (String) hashOperations.get("002", "age");
        System.out.println(age);
//        获得hash结构中的所有字段
        Set keys = hashOperations.keys("002");
        for (Object key : keys) {
            System.out.println(key);
//            获得hash结构中的所有值
            List values = hashOperations.values("002");
            for (Object value : values) {
                System.out.println(value);
            } } }
    //操作List类型的数据
    @Test
    public void testList() {
        ListOperations listOperations = redisTemplate.opsForList();
//        存值
        listOperations.leftPush("mylist", "a");
        listOperations.leftPushAll("mylist", "b", "c", "d");
//        取值
        List<String> mylist = listOperations.range("mylist", 0, -1);
        for (String value : mylist) {
            System.out.println(value);
        }
//        出队列
        Object element = listOperations.rightPop("mylist");
        System.out.println(element);
    }
    //    操作set类型的数据
    @Test
    public void testSet() {
        SetOperations setOperations = redisTemplate.opsForSet();
//        存值
        setOperations.add("myset", "a", "b", "c", "a");
//        取值
        Set<String> myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }
//      删除成员
        setOperations.remove("myset", "a", "b");
//        取值
        myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }
    }
    //    操作ZSet类型的数据
    @Test
    public void testZSet() {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//        存值
        zSetOperations.add("myZset", "a", 10.0);
        zSetOperations.add("myZset", "b", 11.0);
        zSetOperations.add("myZset", "c", 12.0);
        zSetOperations.add("myZset", "a", 13.0);
//                取值
        Set<String> myZSet = zSetOperations.range("myZset", 0, -1);
        for (String s : myZSet) {
            System.out.print(s);//bca
        }
//                修改分数
        zSetOperations.incrementScore("myZset", "b", 20.0);
//                取值
        myZSet = zSetOperations.range("myZset", 0, -1);
        System.out.println();
        for (String s : myZSet) {
            System.out.print(s);//cab
        }
//                删除成员
        zSetOperations.remove("myZset", "a", "b");
//        取值
        myZSet = zSetOperations.range("myZset", 0, -1);
        System.out.println();
        for (String s : myZSet) {
            System.out.print(s);//c
        }
    }
//    通用操作
    @Test
    public void testCommon(){
//        获取Redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.print(key);
        }
//        判断某个key是否存在
        Boolean haha = redisTemplate.hasKey("haha");
        System.out.println(haha);
//        删除指定key
        redisTemplate.delete("myZset");
//        获取指定key对应的value的数据类型
        DataType dataType = redisTemplate.type("myset");
        System.out.println(dataType.name());
    } }
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8月前
|
缓存 NoSQL Redis
[Nestjs] 使用redis的基础配置,以及基本使用的介绍
要在 NestJS 中使用 Redis,需要安装依赖npm install --save redis fastify-redis
251 0
|
4月前
|
存储 SQL NoSQL
Redis的安装及基本使用
Redis的安装及基本使用
|
6月前
|
NoSQL Linux Redis
[笔记]Redis入门-基本使用
[笔记]Redis入门-基本使用
|
9月前
|
消息中间件 存储 缓存
【Redis 系列】redis 学习三,redis 数据结构之 string 和 list 基本使用及熟悉
【Redis 系列】redis 学习三,redis 数据结构之 string 和 list 基本使用及熟悉
|
存储 NoSQL Redis
Redis基本数据类型Zset(有序集合)基本使用
Redis基本数据类型Zset(有序集合)基本使用
|
NoSQL Redis
Redis基本数据类型Set(集合)基本使用
Redis基本数据类型Set(集合)基本使用
|
消息中间件 NoSQL Java
Redis基本数据类型 List(列表)基本使用
Redis基本数据类型 List(列表)基本使用
|
存储 NoSQL Redis
Redis基本数据类型 Hash(哈希)基本使用
Redis基本数据类型 Hash(哈希)基本使用
|
NoSQL 网络协议 测试技术
Redis 中 List 的基本使用 | 学习笔记
快速学习 Redis 中 List 的基本使用
67 0
Redis 中 List 的基本使用 | 学习笔记
|
存储 NoSQL 网络协议
Redis 中 Hash 的基本使用 | 学习笔记
快速学习 Redis 中 Hash 的基本使用
118 0

热门文章

最新文章