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 使用性能差别有多大
![]() | 1 zyxk 2024-01-16 00:23:38 +08:00 我也想知道,等看结果 |
![]() | 2 nagisaushio 2024-01-16 00:26:38 +08:00 via Android 楼主可以贴下测试代码吗?直觉上 redis 应该会慢很多,毕竟隔了个 tcp 传输 |
3 yhtbiy 2024-01-16 00:39:55 +08:00 ![]() 这不是性能的问题吧,Redis 数据是可以持久的,你 go 内存里的重启了数据就都没了 |
4 dobelee 2024-01-16 00:49:58 +08:00 1. 你的例子过于简单,实际业务大多存储结构体,这就涉及编解码和序列化的 CPU 内存消耗。本地缓存无需。 2. 你连接的是本地 redis ,连接耗时忽略,也不存在高峰期的网络波动。没有任何测试意义。 |
![]() | 5 doraemonki 2024-01-16 02:01:59 +08:00 via Android 应该是内置的快,没有持久化需求直接用内置的 map |
6 kneo 2024-01-16 02:09:45 +08:00 via Android ![]() 瞎猜一个一百倍。你可以自己测一下。 |
![]() | 7 Trim21 2024-01-16 02:13:09 +08:00 via Android 内置大概的微秒级,Redis 毫秒级 |
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 。 |
![]() | 9 bianhui 2024-01-16 08:07:11 +08:00 得看,看 key 的数量,结构,数据类型,操作方法。稍微读一下两个源码就知道 |
10 wdmx007 2024-01-16 08:07:20 +08:00 via Android 不是做二级缓存的话,在性能足够的情况下,用 redis 使应用无状态,有利于后续横向扩展 |
11 sxfscool 2024-01-16 08:43:53 +08:00 场景不一样,没什么可比性 |
![]() | 12 sujin190 2024-01-16 08:44:39 +08:00 via Android ![]() 微秒级和纳秒级,如果一个语言标准库 hash 表才有读 redis 的速度,那这语言太废了,没有 4 个数量级的差距说不定都是你用的有问题 |
13 iseki 2024-01-16 08:56:18 +08:00 再注意下,数据序列化/反序列化 |
14 lllllliiii 2024-01-16 08:57:20 +08:00 你看的是什么项目? |
![]() | 15 Nazz 2024-01-16 09:03:56 +08:00 via Android 大概 100ns/op 和 1ms/op 的差异 |
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 倍 |
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 倍 |
![]() | 18 acerphoenix 2024-01-16 09:20:57 +08:00 一个内存读,可能还用 cpu 缓存,一个跨网络读 |
19 alsas 2024-01-16 09:27:44 +08:00 肯定是本地快啊 没经过网络 |
20 zzhaolei 2024-01-16 09:29:01 +08:00 这个测试没意义啊,redis 能持久存储,map 不行,redis 也有一些回收和超时策略,这两个都不是一个东西,使用场景不一样 |
![]() | 21 Rehtt 2024-01-16 09:35:24 +08:00 via Android ![]() 这对比没意义,就像在问火车和远洋轮渡谁快 |
![]() | 22 wzw 2024-01-16 09:41:21 +08:00 小系统可以考虑直接用 goframe 的 gmap, 当缓存, 系统启动的时候, 把所有数据读到 gmap 里面, 速度超级快, 还省了序列化的时间 |
![]() | 23 8355 2024-01-16 09:42:54 +08:00 举个例子 你现在想去厕所 去你家的厕所快 还是去邻居家的厕所快 |
24 wysnxzm 2024-01-16 09:44:07 +08:00 ![]() 我嫉妒你的才华 |
25 nothingistrue 2024-01-16 09:46:12 +08:00 如果性能一样的话,当然是 Redis 的更好,你可以把内存占用、自动超时等烦心事一股脑的扔给 Redis 去处理。 但是性能是否一样,那还另说,不过这块我不擅长,不评论。 再但是,性能是够用就好,不是越高越好。所以,只要性能差距对上层没那么敏感,还是以功能方便为首要选择依据。然而,借用 Redis 做 Map 是增加编码和运维复杂度的,所以一般场景的功能上也会偏向于使用内置 Map 。如果你发现一般场景都用 Redis Map 来取代内置 Map ,那很有可能是内置 Map 太烂了。 |
![]() | 26 RedisMasterNode 2024-01-16 09:51:28 +08:00 有没有一种可能....用 Redis 的人寻求的是一个 "既可快速读写" ,"又可以多个服务(同个服务多个副本)" 访问的 KV 存储.... 我看楼主的意思,应该没有多个副本吧,就一个普通的单实例应用 |
![]() | 27 insert000 2024-01-16 09:53:21 +08:00 又没有可能是集群应用? |
28 realJamespond 2024-01-16 09:56:38 +08:00 tcp 传输完内存都操作几百次,你说哪个快? |
29 QlanQ 2024-01-16 10:05:52 +08:00 你说的这都不是一个事情吧,需求都不一样吧,内存只能单机用呀,会这样写,肯定是预留扩展吧 |
30 qq1340691923 2024-01-16 10:21:31 +08:00 |
31 jonsmith 2024-01-16 10:30:45 +08:00 redis 是数据库,跟本地操作怎么比,语言再拉跨也比网络快啊 |
32 javaisthebest 2024-01-16 10:31:25 +08:00 本地 Map 强多了为什么会出现 Redis? 为什么 Redis 功能这么强大还是会有本地 Map ? 先把这两个问题搞清楚吧。。 别一头雾水就提问 |
33 cloverzrg2 2024-01-16 10:32:07 +08:00 外部的服务缓存,怎么能跟本地内存比速度。 一个网络耗时,就比本地内存数据速度慢几百倍 |
34 tairan2006 2024-01-16 10:32:35 +08:00 分布式缓存和内存缓存的应用场景完全不一样,对比无意义 |
![]() | 35 fgodt 2024-01-16 10:37:13 +08:00 集群应用只能存 redis 自带的再快也不行 |
![]() | 36 shellcodecow 2024-01-16 10:38:34 +08:00 一个是持久化 一个是不是 redis 要 io 耗时的啊 看应用场景分不同用法... 如果是集群应用 那就要用到 redis |
![]() | 37 SethShi 2024-01-16 11:06:09 +08:00 你还是停留在单机呀, 当你上集群的时候, 你还用 map 吗 而且机器之间怎么交换数据, 缓存控制这些 |
38 sampeng 2024-01-16 11:23:52 +08:00 哦。。那你这段数据同时被两个接口做 update ,请问阁下如何应对? |
39 wOuv7i4e7XxsSOR1 2024-01-16 11:41:01 +08:00 莫民奇妙的问题 |
40 wOuv7i4e7XxsSOR1 2024-01-16 11:41:12 +08:00 莫名奇妙的问题 |
![]() | 41 allenby 2024-01-16 12:35:24 +08:00 via Android 肯定是直接内存快 |
![]() | 42 zoharSoul 2024-01-16 12:48:57 +08:00 什么没头没尾的问题, 现在 go 程序员都这样? |
![]() | 43 Daniel17 2024-01-16 13:26:54 +08:00 有没有可能是为了用 redis |
![]() | 44 weijancc 2024-01-16 13:51:12 +08:00 内置 map 肯定更快, 用 redis 是因为在分布式环境下可以共享, 以及可以持久化 |
![]() | 45 zdt3476 2024-01-16 14:00:26 +08:00 这都没必要测试吧,网络 IO 怎么能和内存比 |
46 Seulgi 2024-01-16 14:08:06 +08:00 ![]() 看了这个标题,眉头一皱,看了描述,眉头再皱,不知道具体想问什么问题。看了下面评论,眉头再一皱,还真有人在纠结讨论内置 map 和 redis 的性能。 |
47 aababc 2024-01-16 14:40:48 +08:00 不知道这个帖子想表达和讨论的是什么内容,一脸懵逼 |
![]() | 48 Vegetable 2024-01-16 14:57:46 +08:00 |
49 darklost 2024-01-16 14:58:07 +08:00 多台机器跑横向扩展的时候就知道了 |
50 huyan3280 2024-01-16 15:00:18 +08:00 这还用想,redis 有 IO 呀,当然是内存, |
![]() | 51 xuanbg 2024-01-16 16:55:25 +08:00 肯定 Redis 要慢!但 Redis 可以持久化,也可以多机共享,这是你内存里面的 map 做不到的。所以,什么时候要用 Redis ,就很清楚了。 |
![]() | 52 flyingghost 2024-01-17 11:24:05 +08:00 "一段需要保存的文本" 我发现一段文本用变量来存比用磁盘来存快上万倍哎! |
53 e7 2024-01-17 11:50:11 +08:00 这属于常识性的问题,说明 op 还没入门啊 |
54 adgfr32 2024-01-17 14:51:19 +08:00 本地存 map 的话, 要考虑不常用的数据回收掉, 不然内存一直涨. 还要考虑持久化, 多节点的话数据不一致. 折腾这么多不如直接 redis 了. redis 肯定是慢的, 因为需要通过网络获取数据, 慢多少取决于网络上消耗了多少 |