Back to questions
Junior — Middle
92
Возможно ли реализовать отдельные операции записи и чтения с использованием различных шардов?
Companies where asked
Indrive
Answer from AI
sobes.tech AI
Да, в Go можно реализовать отдельные операции записи и чтения с использованием различных шардов (частей) для повышения производительности и уменьшения блокировок.
Идея заключается в том, чтобы разбить общую структуру данных на несколько шардов — независимых подструктур, каждая со своей блокировкой (например, mutex). Записи и чтения направляются в соответствующий шард по хешу ключа.
Преимущества:
- Параллельные операции с разными ключами могут выполняться без взаимных блокировок.
- Уменьшается конкуренция за одну глобальную блокировку.
Пример упрощённой реализации шардированной карты:
import (
"hash/fnv"
"sync"
)
type shard struct {
sync.RWMutex
m map[string]interface{}
}
type ShardedMap struct {
shards []shard
}
func NewShardedMap(numShards int) *ShardedMap {
shards := make([]shard, numShards)
for i := range shards {
shards[i].m = make(map[string]interface{})
}
return &ShardedMap{shards: shards}
}
func (sm *ShardedMap) getShard(key string) *shard {
h := fnv.New32a()
h.Write([]byte(key))
return &sm.shards[uint(h.Sum32())%uint(len(sm.shards))]
}
func (sm *ShardedMap) Set(key string, value interface{}) {
s := sm.getShard(key)
s.Lock()
defer s.Unlock()
s.m[key] = value
}
func (sm *ShardedMap) Get(key string) (interface{}, bool) {
s := sm.getShard(key)
s.RLock()
defer s.RUnlock()
val, ok := s.m[key]
return val, ok
}
Таким образом, операции записи и чтения распределяются по разным шардовым мьютексам, что повышает масштабируемость.