Redis 5 データ構造に適用できるシナリオ

オンラインでの紹介は一般的すぎます。理解できる適用可能なシナリオをいくつか苦労してまとめました。下の図を参照してください。

redis-cli 命令の完全なコレクション:クリックして redis 命令を表示します

Redis は 5 つのデータ型をサポートしています。

  1. ハッシュ

  1. リスト

  1. セット

  1. zset(ソートされたセット:順序付きセット)

文字列は Redis の最も基本的なタイプであり、1 つのキーが 1 つの値に対応します。実際、value は String だけでなく、数値でもあります。

使用シナリオ: 一般的なキーと値のキャッシュ アプリケーション。通常のカウント (増分): Weibo の数、ファンの数、いいね! の数など。

一般的なコマンド set、get incr、incrby、decrby、del


ハッシュは、キーと値 (キー => 値) ペアのコレクションです。特に物品の保管に適しています。

次の情報を含むユーザー情報オブジェクト データを保存するには:

ユーザーIDが検索対象のキーとなり、格納される値のユーザーオブジェクトには名前、年齢、誕生日などの情報が含まれます。通常のキー/値構造を使用して格納される場合、

通常、次の 2 つの方法を選択します。

1 つ目の方法は、ユーザー ID を検索キーとして、その他の情報をオブジェクトにカプセル化してシリアル化して保存する方法ですが、シリアル化/逆シリアル化のオーバーヘッドが増加することと、いずれかの項目をシリアル化する必要があるという欠点があります。情報を取得する場合、オブジェクト全体を取得する必要があり、変更操作では同時実行性を保護する必要があるため、CAS などの複雑な問題が発生します。

2 番目の方法は、ユーザー情報オブジェクトのメンバーと同じ数のキーと値のペアを格納し、ユーザー ID と対応する属性の名前を一意の識別子として使用して、対応する属性の値を取得します。ただし、シリアル化のオーバーヘッドは発生します。同時実行の問題は解消されますが、ユーザー ID は繰り返し保存されるため、そのようなデータが大量にある場合は、依然としてかなりのメモリの浪費が発生します。

一般的に使用されるコマンド:

hset,hget,mset ,mget

本のオブジェクト名、ページ、属性およびキーとしてのモンティ

hset、hgetは属性情報の保存に適しており、mset、mgetは複数のキーを一度に設定するのに適しています。

ハッシュを個別に変更して属性を指定できますか? はい、もう一度保存してください

キーをすぐに削除するにはどうすればよいですか?

hgetall取出来的数据结构是什么,怎么取数据?map[string]string

func HsetGet(conn redis.Conn){
    key := "abc"
    _, err := conn.Do("hset", "books", key, "1") //books是哈希表名 其中存的是一条条key-value
    if err != nil {
        fmt.Printf("set failed:%s", err)
        return
    }
    _, err = conn.Do("hset", "books", "efg", "2") //books是哈希表名 其中存的是一条条key-value
    if err != nil {
        fmt.Printf("-----set failed:%s", err)
        return
    }
    // 取单个值
    data, err := redis.String(conn.Do("hget", "books", key)) //books是哈希表名 其中存的是一条条key-value
    if err != nil {
        fmt.Printf("get failed, err:%v", err)
        return
    }
    fmt.Printf("HsetGet key:%s value:%s \n", key, data)
    // 取全部值
    all, err := redis.StringMap(conn.Do("hgetall", "books")) //books是哈希表名 其中存的是一条条key-value
    if err != nil {
        fmt.Printf("get failed, err:%v", err)
        return
    }
    fmt.Println("all.abc ",all["abc"])

    allByte ,_:= json.Marshal(all)
    fmt.Println(string(allByte))
    var result = make(map[string]string,0)
    json.Unmarshal(allByte,&result)
    fmt.Println(result["page"])
    for k,v := range result {
        fmt.Println("k:",k,"v:",v)
    }
    redis.StringMap(conn.Do("del", "books"))  // 删除key

}

list列表是简单的字符串列表,按照插入顺序排序。

应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现,通过lpush往列表里插入新元素,然后通过lrange命令读取最新元素列表,如朋友圈点赞、评论列表。

点对点的简单消息队列应用(lpop 和lpush 实现)

定时计算的排行榜,lrage可以用取数据。非定时的话,数据会多一些需要排序。

常用指令:lpush:左入队,lpop

如何一次性取出所有数据?如何删除数据?

用lrange取出,数据结构是数组

del key即可删除list列表

import (
    "encoding/json"
    "runtime"
    "testing"
    "time"
    //"github.com/go-redis/redis"  这个包是首选
    "github.com/garyburd/redigo/redis"
    "fmt"
)

func  main(){
db := &redis.Pool{
        MaxIdle:     1,
        MaxActive:   3,
        IdleTimeout: 4 * time.Second,
        Dial: func() (redis.Conn, error) {
            c, err := redis.DialURL("redis://192.168.1.201:6379/10")
            if err != nil {
                fmt.Printf("redis connection error: %v \n", err)
                return nil, fmt.Errorf("redis connection error: %s", err)
            }
            return c, err
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            _, err := c.Do("PING")
            if err != nil {
                fmt.Printf("ping redis error: %v \n", err)
                return fmt.Errorf("ping redis error: %v", err)
            }
            return nil
        },
    }
    c := db.Get()
    defer c.Close()
     List(c)
}

func List(conn redis.Conn){
    _, err := conn.Do("del", "book_stack" ) //左边进 第二个参数book_lsit是队列名
    if err != nil {
        fmt.Printf("del set failed:%s \n", err)
        return
    }

    _, err = conn.Do("lpush", "book_stack", 1, 2,3,4,5) //左边进 第二个参数book_lsit是队列名
    if err != nil {
        fmt.Printf("List set failed:%s \n", err)
        return
    }

    data, err := redis.String(conn.Do("lpop", "book_stack")) //左边出,一次只能出队一个元素
    if err != nil {
        fmt.Printf("List get failed, err:%v \n", err)
        return
    }
    fmt.Printf("data  value:%s \n", data)
    lrange, err := redis.Int64s(conn.Do("lrange", "book_stack", 0,-1) )//左边出,一次只能出队一个元素
    if err != nil {
        fmt.Printf("List get failed, err:%v \n", err)
        return
    }
    for k,v := range lrange {
        fmt.Println("k:",k,"v:",v)
    }
    fmt.Printf("lrange  value:%v \n", lrange)
}

set是string类型的无序不重合集合。 set 数据有序?纯数字的一般是有序的,其他的确实是无序,所以整体是无序。数据类型是interface,可以同时添加不同类型数据

127.0.0.1:6379[10]> sadd gg 20 200 60 600 qq oo pp aa ss
(integer) 4
127.0.0.1:6379[10]> smembers gg
1) "3"
2) "20"
3) "200"
4) "2"
5) "oo"
6) "pp"
7) "qq"
8) "ss"
9) "4"
10) "60"
11) "aa"
12) "600"
13) "1"

集合是通过hashtable实现的,概念和数学中个的集合基本类似,可以交集,并集,差集等等,set中的元素是没有顺序的。所以添加,删除,查找的复杂度都是O(1)。

常用命令: sadd(添加多个),smembers(获取数据),scard(元素数量),srem(移除一个或多个元素),Sismember (判断成员元素是否是集合的成员),Sscan (命令用于迭代集合键中的元素)。

Sinter 命令返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。 sinter key1 ke2 ...

如何直接判断元素在set集合内是否存在?而不是遍历去查看

sismember key xxx(元素)

场景:用户关注的人,用户的粉丝,共同好友,共同关注,共同爱好,微信抽奖小程序

微信微博点赞,收藏、标签。详细的使用快点这里呀 点击查看呀

更多指令参考这里:点击查看redis指令


zset和 set 一样也是string类型元素的集合,且不允许重复的成员。 *zadd 命令:*添加元素到集合,元素在集合中存在则更新对应score。 常用命令:zadd,zrange,zrem,zcard等

不同的是每个元素都会关联一个double类型的分数。Redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

使用场景:Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。

使用场景:微信步数排行榜、玩家游戏排行榜、成绩单排名。

更多使用场景,查看这里,真的很详细。https://www.jianshu.com/p/f00128af8dbf

go redis相关使用代码示例,跳转这里

参考链接:

https://blog.csdn.net/ckckckcckckc/article/details/127727334

http://t.zoukankan.com/forever521Lee-p-9494951.html

redis高可用方案

https://www.jianshu.com/p/7d5fbf90bcd7

https://www.jianshu.com/p/f439da2b2d2d 哨兵模式详解

Supongo que te gusta

Origin blog.csdn.net/xia_2017/article/details/128618821
Recomendado
Clasificación