V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
huahsiung
V2EX  ›  程序员

go 语言直接使用 map 和连接 Redis 后使用 Map 性能差别有多大

  •  
  •   huahsiung · 2024-01-16 00:13:14 +08:00 · 4726 次点击
    这是一个创建于 381 天前的主题,其中的信息可能已经有所发展或是发生改变。

    go 语言直接使用 map 很方便

    map1 := make(map[string]int)
    key1 := map1["str1"]
    

    但是发现有些 go 项目源码偏向使用 Redis 等第三方的 map.

    import (
        github.com/go-redis/redis"
    )
     client := redis.NewClient(&redis.Options{
            Addr:     "localhost:6379", 
            Password: "",               
            DB:       0,                
        })
    client.Ping()
    client.HSet("myhash", "key1", "value1")
    value1, err := client.HGet("myhash", "")
    

    然后看到项目的 map 并不是并发使用的,数据量也不是特别大。(有些并没有持久需求的也在使用 redis )

    go map 和 redis map 都是内存使用的,而且速度也很快。但是很多需要查找 hash 关系表的项目,偏向使用如 redis map 等第三方表。

    我粗略测试了一下,没看出什么区别(可能我测试数据较小)。如果排除 go map 不能并发读写外与 Redis Map 使用性能差别有多大

    54 条回复    2024-01-17 14:51:19 +08:00
    zyxk
        1
    zyxk  
       2024-01-16 00:23:38 +08:00
    我也想知道,等看结果
    nagisaushio
        2
    nagisaushio  
       2024-01-16 00:26:38 +08:00 via Android
    楼主可以贴下测试代码吗?直觉上 redis 应该会慢很多,毕竟隔了个 tcp 传输
    yhtbiy
        3
    yhtbiy  
       2024-01-16 00:39:55 +08:00   ❤️ 3
    这不是性能的问题吧,Redis 数据是可以持久的,你 go 内存里的重启了数据就都没了
    dobelee
        4
    dobelee  
       2024-01-16 00:49:58 +08:00
    1. 你的例子过于简单,实际业务大多存储结构体,这就涉及编解码和序列化的 CPU 内存消耗。本地缓存无需。
    2. 你连接的是本地 redis ,连接耗时忽略,也不存在高峰期的网络波动。没有任何测试意义。
    doraemonki
        5
    doraemonki  
       2024-01-16 02:01:59 +08:00 via Android
    应该是内置的快,没有持久化需求直接用内置的 map
    kneo
        6
    kneo  
       2024-01-16 02:09:45 +08:00 via Android   ❤️ 1
    瞎猜一个一百倍。你可以自己测一下。
    Trim21
        7
    Trim21  
       2024-01-16 02:13:09 +08:00 via Android
    内置大概的微秒级,Redis 毫秒级
    jinliming2
        8
    jinliming2  
       2024-01-16 03:33:11 +08:00 via iPhone
    虽然不知道 go 原生 map 和用 Redis 的性能差异,即便是 Redis 更快,为什么只用 localhost:port 的 TCP 连接本地回环的方式来访问 Redis 呢?在 Linux 上使用 unix domain sockets 的方式不是会更快吗?根据 Redis 官方文档上的数据,unix sockets 的吞吐量能提高 50%。
    而不支持 unix sockets 的 windows 貌似用 Redis 本身就有性能瓶颈,感觉还不如直接用 go 原生 map 。
    bianhui
        9
    bianhui  
       2024-01-16 08:07:11 +08:00
    得看,看 key 的数量,结构,数据类型,操作方法。稍微读一下两个源码就知道
    wdmx007
        10
    wdmx007  
       2024-01-16 08:07:20 +08:00 via Android
    不是做二级缓存的话,在性能足够的情况下,用 redis 使应用无状态,有利于后续横向扩展
    sxfscool
        11
    sxfscool  
       2024-01-16 08:43:53 +08:00
    场景不一样,没什么可比性
    sujin190
        12
    sujin190  
       2024-01-16 08:44:39 +08:00 via Android   ❤️ 2
    微秒级和纳秒级,如果一个语言标准库 hash 表才有读 redis 的速度,那这语言太废了,没有 4 个数量级的差距说不定都是你用的有问题
    iseki
        13
    iseki  
       2024-01-16 08:56:18 +08:00
    再注意下,数据序列化/反序列化
    fzdwx
        14
    fzdwx  
       2024-01-16 08:57:20 +08:00
    你看的是什么项目?
    Nazz
        15
    Nazz  
       2024-01-16 09:03:56 +08:00 via Android
    大概 100ns/op 和 1ms/op 的差异
    bthulu
        16
    bthulu  
       2024-01-16 09:14:47 +08:00
    测试代码
    ```
    Dictionary<int, int> dict = new() { { 1, 1 } };
    Stopwatch stopwatch = Stopwatch.StartNew();
    int i = dict[1];
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedTicks);
    using ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
    IDatabase database = redis.GetDatabase();
    database.HashSet("key", 1, 1);
    stopwatch = Stopwatch.StartNew();
    RedisValue redisValue = database.HashGet("key", 1);
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedTicks);
    ```

    测试结果:
    ```
    746
    18209
    ```

    一句话: 内存 map 快 25 倍
    bthulu
        17
    bthulu  
       2024-01-16 09:17:49 +08:00
    更新重复一万次测试结果
    ```
    Dictionary<int, int> dict = new() { { 1, 1 } };
    Stopwatch stopwatch = Stopwatch.StartNew();
    for (int i = 0; i < 10000; i++)
    {
    int j = dict[1];
    }
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedTicks);
    using ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
    IDatabase database = redis.GetDatabase();
    database.HashSet("key", 1, 1);
    stopwatch = Stopwatch.StartNew();
    for (int i = 0; i < 10000; i++)
    {
    RedisValue redisValue = database.HashGet("key", 1);
    }
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedTicks);
    ```
    输出
    ```
    1228
    9577919
    ```
    一句话: 内存 map 快 7800 倍
    acerphoenix
        18
    acerphoenix  
       2024-01-16 09:20:57 +08:00
    一个内存读,可能还用 cpu 缓存,一个跨网络读
    alsas
        19
    alsas  
       2024-01-16 09:27:44 +08:00
    肯定是本地快啊 没经过网络
    zzhaolei
        20
    zzhaolei  
       2024-01-16 09:29:01 +08:00
    这个测试没意义啊,redis 能持久存储,map 不行,redis 也有一些回收和超时策略,这两个都不是一个东西,使用场景不一样
    Rehtt
        21
    Rehtt  
       2024-01-16 09:35:24 +08:00 via Android   ❤️ 3
    这对比没意义,就像在问火车和远洋轮渡谁快
    wzw
        22
    wzw  
       2024-01-16 09:41:21 +08:00
    小系统可以考虑直接用 goframe 的 gmap, 当缓存,

    系统启动的时候, 把所有数据读到 gmap 里面,

    速度超级快, 还省了序列化的时间
    8355
        23
    8355  
       2024-01-16 09:42:54 +08:00
    举个例子
    你现在想去厕所
    去你家的厕所快
    还是去邻居家的厕所快
    wysnxzm
        24
    wysnxzm  
       2024-01-16 09:44:07 +08:00   ❤️ 3
    我嫉妒你的才华
    nothingistrue
        25
    nothingistrue  
       2024-01-16 09:46:12 +08:00
    如果性能一样的话,当然是 Redis 的更好,你可以把内存占用、自动超时等烦心事一股脑的扔给 Redis 去处理。

    但是性能是否一样,那还另说,不过这块我不擅长,不评论。

    再但是,性能是够用就好,不是越高越好。所以,只要性能差距对上层没那么敏感,还是以功能方便为首要选择依据。然而,借用 Redis 做 Map 是增加编码和运维复杂度的,所以一般场景的功能上也会偏向于使用内置 Map 。如果你发现一般场景都用 Redis Map 来取代内置 Map ,那很有可能是内置 Map 太烂了。
    RedisMasterNode
        26
    RedisMasterNode  
       2024-01-16 09:51:28 +08:00
    有没有一种可能....用 Redis 的人寻求的是一个 "既可快速读写" ,"又可以多个服务(同个服务多个副本)" 访问的 KV 存储....

    我看楼主的意思,应该没有多个副本吧,就一个普通的单实例应用
    insert000
        27
    insert000  
       2024-01-16 09:53:21 +08:00
    又没有可能是集群应用?
    realJamespond
        28
    realJamespond  
       2024-01-16 09:56:38 +08:00
    tcp 传输完内存都操作几百次,你说哪个快?
    QlanQ
        29
    QlanQ  
       2024-01-16 10:05:52 +08:00
    你说的这都不是一个事情吧,需求都不一样吧,内存只能单机用呀,会这样写,肯定是预留扩展吧
    qq1340691923
        30
    qq1340691923  
       2024-01-16 10:21:31 +08:00
    jonsmith
        31
    jonsmith  
       2024-01-16 10:30:45 +08:00
    redis 是数据库,跟本地操作怎么比,语言再拉跨也比网络快啊
    javaisthebest
        32
    javaisthebest  
       2024-01-16 10:31:25 +08:00
    本地 Map 强多了为什么会出现 Redis?

    为什么 Redis 功能这么强大还是会有本地 Map ?

    先把这两个问题搞清楚吧。。 别一头雾水就提问
    cloverzrg2
        33
    cloverzrg2  
       2024-01-16 10:32:07 +08:00
    外部的服务缓存,怎么能跟本地内存比速度。
    一个网络耗时,就比本地内存数据速度慢几百倍
    tairan2006
        34
    tairan2006  
       2024-01-16 10:32:35 +08:00
    分布式缓存和内存缓存的应用场景完全不一样,对比无意义
    fgodt
        35
    fgodt  
       2024-01-16 10:37:13 +08:00
    集群应用只能存 redis 自带的再快也不行
    shellcodecow
        36
    shellcodecow  
       2024-01-16 10:38:34 +08:00
    一个是持久化 一个是不是 redis 要 io 耗时的啊 看应用场景分不同用法...

    如果是集群应用 那就要用到 redis
    seth19960929
        37
    seth19960929  
       2024-01-16 11:06:09 +08:00
    你还是停留在单机呀, 当你上集群的时候, 你还用 map 吗
    而且机器之间怎么交换数据, 缓存控制这些
    sampeng
        38
    sampeng  
       2024-01-16 11:23:52 +08:00
    哦。。那你这段数据同时被两个接口做 update ,请问阁下如何应对?
    wOuv7i4e7XxsSOR1
        39
    wOuv7i4e7XxsSOR1  
       2024-01-16 11:41:01 +08:00
    莫民奇妙的问题
    wOuv7i4e7XxsSOR1
        40
    wOuv7i4e7XxsSOR1  
       2024-01-16 11:41:12 +08:00
    莫名奇妙的问题
    allenby
        41
    allenby  
       2024-01-16 12:35:24 +08:00 via Android
    肯定是直接内存快
    zoharSoul
        42
    zoharSoul  
       2024-01-16 12:48:57 +08:00
    什么没头没尾的问题, 现在 go 程序员都这样?
    Daniel17
        43
    Daniel17  
       2024-01-16 13:26:54 +08:00
    有没有可能是为了用 redis
    weijancc
        44
    weijancc  
       2024-01-16 13:51:12 +08:00
    内置 map 肯定更快, 用 redis 是因为在分布式环境下可以共享, 以及可以持久化
    zdt3476
        45
    zdt3476  
       2024-01-16 14:00:26 +08:00
    这都没必要测试吧,网络 IO 怎么能和内存比
    Seulgi
        46
    Seulgi  
       2024-01-16 14:08:06 +08:00   ❤️ 5
    看了这个标题,眉头一皱,看了描述,眉头再皱,不知道具体想问什么问题。看了下面评论,眉头再一皱,还真有人在纠结讨论内置 map 和 redis 的性能。
    aababc
        47
    aababc  
       2024-01-16 14:40:48 +08:00
    不知道这个帖子想表达和讨论的是什么内容,一脸懵逼
    Vegetable
        48
    Vegetable  
       2024-01-16 14:57:46 +08:00
    darklost
        49
    darklost  
       2024-01-16 14:58:07 +08:00
    多台机器跑横向扩展的时候就知道了
    huyan3280
        50
    huyan3280  
       2024-01-16 15:00:18 +08:00
    这还用想,redis 有 IO 呀,当然是内存,
    xuanbg
        51
    xuanbg  
       2024-01-16 16:55:25 +08:00
    肯定 Redis 要慢!但 Redis 可以持久化,也可以多机共享,这是你内存里面的 map 做不到的。所以,什么时候要用 Redis ,就很清楚了。
    flyingghost
        52
    flyingghost  
       2024-01-17 11:24:05 +08:00
    "一段需要保存的文本"

    我发现一段文本用变量来存比用磁盘来存快上万倍哎!
    e7
        53
    e7  
       2024-01-17 11:50:11 +08:00
    这属于常识性的问题,说明 op 还没入门啊
    z1829909
        54
    z1829909  
       2024-01-17 14:51:19 +08:00
    本地存 map 的话, 要考虑不常用的数据回收掉, 不然内存一直涨. 还要考虑持久化, 多节点的话数据不一致. 折腾这么多不如直接 redis 了. redis 肯定是慢的, 因为需要通过网络获取数据, 慢多少取决于网络上消耗了多少
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   748 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 23:08 · PVG 07:08 · LAX 15:08 · JFK 18:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.