Golang Go语言中求一个支持并发读写的数据结构

发布于 1周前 作者 bupafengyu 来自 Go语言

Golang Go语言中求一个支持并发读写的数据结构

场景是,先加载 500 万个 sha256 字符串到内存中,后面会需要大量的对这 500 万个字符串进行查找操作。

现在的实现方法是用 map,先单线程加载 500 万个字符串到 map 中,但是插入效率低。有没有其他支持并发写,且查询效率高的数据结构。

写和读是分开的。不存在同时读写的情况。

17 回复

你这个题目和内容是相反的呀。

更多关于Golang Go语言中求一个支持并发读写的数据结构的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


goroutine+chan 可以么

map 可以根据 key 先拆掉, 不要放在一个 map 中

4L 正解, 对 key 做一个 hash,分成很多份。

你这要求需要细化下
用的啥语言?要多久加载能满足要求?查询延迟要求是多少?有多少线程会去查?是在线 service 还是一次性脚本,还是别的定时 job ?这些都影响设计。

假如是 java,你直接上 concurrenthashmap 是否可以满足需求?

或者像前面说的那样,把 key 分段读写。

复杂点,能不能先并发插入 concurrenthashmap,先应付着查询,然
后台起个线程再慢慢拷贝到普通 map,弄完了来个原子交换。缺点是内存峰值会大不少

忽略我,原来在 go 节点下面

分段吧 ,空间换时间

Redis 可以存吗

写效率低,你就去优化写效率

影响 map 读写效率的的因素:
1. 哈希的计算
2. 扩缩容
3. 处理哈希冲突

ps.已知条件太少,单从你给的条件看,可做的“优化”多了去了

哈希插入和查询都是 o1 的,除非有碰撞,那就找个合适的碰撞函数,你已经放内存里了。
插入慢就多线程。

这个是静态存储吗?如果是只读不写,建议食用 groupcache 。

ConcurrentMap,可以并发插入

Trie tree,怎么用 map 呢,占太多内存当然太慢了大哥

在Go语言中,如果你需要一个支持并发读写的数据结构,有几种常见的选择。这些数据结构主要通过使用Go的并发原语(如goroutines和channels)以及内置的sync包来实现线程安全。

  1. sync.Map

    • sync.Map 是Go标准库中提供的一个线程安全的map实现,适用于高并发的读写操作。
    • 它提供了StoreLoadLoadOrStoreDeleteRange等方法来操作键值对。
    • sync.Map 的性能在大多数情况下优于使用锁来保护的传统map。
  2. sync.RWMutex

    • 你也可以使用sync.RWMutex来保护一个普通的map,实现自定义的并发安全数据结构。
    • RWMutex 提供了读锁(RLock/RUnlock)和写锁(Lock/Unlock),允许多个读操作并发进行,但写操作会阻塞其他读写操作。
  3. channel-based structures

    • 对于更复杂的并发数据结构,如队列、栈等,你可以使用Go的channel来实现线程安全的队列或栈。
    • Channel 本质上是一个FIFO(先进先出)的队列,可以用于在goroutines之间传递数据。
    • 通过合理地使用select语句和buffered/unbuffered channels,可以实现复杂的并发控制逻辑。

选择哪种数据结构取决于你的具体需求,包括读写操作的频率、数据的复杂性和性能要求。在大多数情况下,sync.Map 是一个简单而有效的选择。

回到顶部