redis相關知識點

2022-06-20 21:01:53

redis 的相關知識點

啟動

  1. 啟動程式碼

     redis-cli -a 密碼
    

通用命令

expire: 設定有效期

expire name 10

key

key *

相關資料型別

String

set:新增或者修改已經存在的一個String型別的鍵值對

set age 19

get:根據key獲取String型別的value

get age

mset:批次新增多個String型別的鍵值對

mset k1 v1 k2 v2

mget:根據多個key獲取多個String型別的value

mget k1 k2

incr:讓一個整型的key自增1

 incr age 
 19--->20

incrby:讓一個整型的key自增並指定步長

incrby age 2
incrby age -1

incrbyfloat:讓一個浮點型別的數位自增並指定步長

incrbyfloat score 0.5

setnx:新增一個String型別的鍵值對,前提是這個key不存在,否則不執行

setnx name leixin

setex:新增一個String型別的鍵值對,並且指定有效期

 setex names 10 "leixin"

Hash型別

HSET key field value:新增或者修改hash型別key的field的值

 hset leixin:name name "leixin"
 hset leixin:name name2 "leixin"

HGET key field:獲取一個hash型別key的field的值

hget leixin:name name2

HMSET:批次新增多個hash型別key的field的值
HMGET:批次獲取多個hash型別key的field的值
HGETALL:獲取一個hash型別的key中的所有的field和value

hgetall leixin:name

HKEYS:獲取一個hash型別的key中的所有的field

hkeys leixin:name

HVALS:獲取一個hash型別的key中的所有的value

hvals leixin:name

HINCRBY:讓一個hash型別key的欄位值自增並指定步長

hincrby leixin:name age 2

HSETNX:新增一個hash型別的key的field值,前提是這個field不存在,否則不執行

List

特徵與LinkedList類似:

  • 有序
  • 元素可以重複
  • 插入和刪除快
  • 查詢速度一般
  • 常用來儲存一個有序資料,例如:朋友圈點贊列表,評論列表等。

如何利用List結構模擬一個棧?

入口和出口在同一邊

如何利用List結構模擬一個佇列?

入口和出口在不同邊

如何利用List結構模擬一個阻塞佇列?

入口和出口在不同邊出隊時採用BLPOP或BRPOP


  1. LPUSH key element ... :向列表左側插入一個或多個元素

    lpush users 1 2 3 4 5
    

    此時實際為 5 4 3 2 1

  2. RPUSH key element ... :向列表右側插入一個或多個元素

     rpush users 6 7
    

    此時實際為 5 4 3 2 1 6 7

  3. LPOP key count:移除並返回列表左側的count個元素,沒有則返回nil

     lpop users 3
    

    此時移除並返回 5 4 3

  4. RPOP key count:移除並返回列表右側的count元素

     rpop users 3
    

    此時移除並返回的是 7 6 1

  5. LRANGE key star end:返回一段角標範圍內的所有元素

     lrange users 0 0
    

    此時返回的是 2

  6. BLPOP和BRPOP:與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil

     blpop users2 100
    

    此時等待中

    這個時候新開一個控制檯

    lpush users2 1
    

    此時不超過100s的話就會出來結果

    1) "users2"
    2) "1"
    (34.91s)
    

Set

Redis的Set結構與Java中的HashSet類似,可以看做是一個value為null的HashMap。因為也是一個hash表,因此具備與HashSet類似的特徵:

  • 無序
  • 元素不可重複
  • 查詢快
  • 支援交集、並集、差集等功能
  1. SADD key member ... :向set中新增一個或多個元素

    sadd s1 a b c
    
  2. SREM key member ... : 移除set中的指定元素

    srem s1 a
    
  3. SCARD key: 返回set中元素的個數

    scard s1
    
  4. SISMEMBER key member:判斷一個元素是否存在於set中

    sismember s1 b
    
  5. SMEMBERS:獲取set中的所有元素

    smembers s1
    
  6. SINTER key1 key2 ... :求key1與key2的交集

  7. SDIFF key1 key2 ... :求key1與key2的差集

  8. SUNION key1 key2 ..:求key1和key2的並集

SortedSet

  • 可排序
  • 元素不重複
  • 查詢速度快
  1. ZADD key score member:新增一個或多個元素到sorted set ,如果已經存在則更新其score值

    zadd students 87 jack 88 jerry
    
  2. ZREM key member:刪除sorted set中的一個指定元素

    zrem students jack
    
  3. ZSCORE key member : 獲取sorted set中的指定元素的score值

    zscore students jerry
    
  4. ZRANK key member:獲取sorted set 中的指定元素的排名

     zrank students jerry
    

    排名是從0開始的

  5. ZCARD key:獲取sorted set中的元素個數

     zcard students
    
  6. ZCOUNT key min max:統計score值在給定範圍內的所有元素的個數

  7. ZINCRBY key increment member:讓sorted set中的指定元素自增,步長為指定的increment值

  8. ZRANGE key min max:按照score排序後,獲取指定排名範圍內的元素

  9. ZRANGEBYSCORE key min max:按照score排序後,獲取指定score範圍內的元素

  10. ZDIFF、ZINTER、ZUNION:求差集、交集、並集

  11. 注意:所有的排名預設都是升序,如果要降序則在命令的Z後面新增REV即可

SpringDataRedis

API 返回值型別 說明
redisTemplate.opsForValue() ValueOperations 操作String型別資料
redisTemplate.opsForHash() HashOperations 操作Hash型別資料
redisTemplate.opsForList() ListOperations 操作List型別資料
redisTemplate.opsForSet() SetOperations 操作Set型別資料
redisTemplate.opsForZSet() ZSetOperations 操作SortedSet型別資料
redisTemplate 通用的命令

快速入門

  1. 匯入依賴

    <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
    </dependency>
    <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
    </dependency>
    
  2. 組態檔

    spring:
      redis:
        host: 192.168.122.120
        port: 6379
        password: 73883672
        jedis:
          pool:
            max-active: 8
            max-idle: 0
            max-wait: 100ms
    
  3. 進行測試

    @Autowired
        private RedisTemplate redisTemplate;
        @Test
        void testString() {
            //寫入一條String資料
            redisTemplate.opsForValue().set("name","google");
            //獲取String資料
            Object name = redisTemplate.opsForValue().get("name");
            System.out.println(name);
        }
    
  4. 此時會發現redis資料庫只有一些轉碼了的序列,此時我們需要進行手動序列化

    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            // 建立RedisTemplate物件
            RedisTemplate<String, 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;
        }
    }
    
    
    
  5. 此時測試注入物件

     @Test
        void testSaveUser(){
            //User有兩個引數,一個是name,一個是age
            redisTemplate.opsForValue().set("user:100",new User("leixin",20));
            User o =(User) redisTemplate.opsForValue().get("user:100");
            System.out.println("o = "+o);
        }
    
  6. 此時發現多了一個class引數,資料量一大,這是非常浪費空間的。

    {
      "@class": "com.leixin.pojo.User",
      "name": "leixin",
      "age": 20
    }
    

簡單優化

  1. 使用StringRedisTemplate
  2. 寫入Redis時,手動把物件序列化為JSON
  3. 讀取Redis時,手動把讀取到的JSON反序列化為物件
 @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Test
    void testString(){
    stringRedisTemplate.opsForValue().set("name","leixin");
    String name = stringRedisTemplate.opsForValue().get("name");
    System.out.println(name);

}

    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    void testSaveUser() throws JsonProcessingException {
        // 建立物件
        User user = new User("虎哥", 21);
        // 手動序列化
        String json = mapper.writeValueAsString(user);
        // 寫入資料
        stringRedisTemplate.opsForValue().set("user:200", json);

        // 獲取資料
        String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
        // 手動反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        System.out.println("user1 = " + user1);
    }
	@Test
    void testHash() {
        stringRedisTemplate.opsForHash().put("user:400", "name", "虎哥");
        stringRedisTemplate.opsForHash().put("user:400", "age", "21");

        Map<Object, Object> entries = 		stringRedisTemplate.opsForHash().entries("user:400");
        System.out.println("entries = " + entries);
    }