Dependiendo del introducirde estructura de datos, MemoryStoreService establece límites en la memoria y el número de artículos en una estructura de datos. Todas las estructuras de datos están también limitadas por un límite de solicitudes global por partición.
Cada experiencia de Roblox tiene el Panel de Observabilidad de Almacenamiento de Memoria, que incluye un conjunto de gráficos que puedes usar para monitorear el uso del almacenamiento de memoria.
Mapas y colas clasificadas
Ambas los mapas y colas tienen límites en el número máximo de artículos y el máximo de memoria. Además, los elementos en uno de estos datos estructura de mapeo siempre residen en una sola partición. Cada solicitud a una de estas estructuras de datos es una solicitud a la misma partición.
Cuando un mapa o cola clasificada alcanza su límite de artículos o memoria, la mejor manera de progresar es eliminar los elementos no deseados manualmente o agregando una política de expiración para los elementos. Alternativamente, si solo el límite de memoria está causando esto, puede intentar reducir el tamaño de sus artículos eliminando información no deseada de sus llaves y valores.
Si necesita todos sus artículos o está experimentando un estrangulamiento debido a la solicitud de rendimiento, la única solución es sharding.
dividiendo
La fragmentación es el proceso de almacenar un conjunto de datos relacionados en múltiples estructuras de datos. En otras palabras, significa tomar una estructura de datos existente y reemplazarla con múltiples, más pequeñas que contienen el mismo conjunto de datos que el original.
El desafío clave para dividir es encontrar una manera de distribuir los datos en múltiples estructuras de datos de una manera que mantenga la misma funcionalidad que el original.
Agregar una Mapa Ordenado
Para dividir un mapa clasificado, considere dividir sus datos en subsecciones alfabéticas con rangos de personaje. Por ejemplo, asuma que solo tiene llaves con la primera letra de A-Z y cree que cuatro subsecciones clasificadas son suficientes para su caso de uso actual y futuro:
- El primer mapa puede cubrir A-G, el segundo H-N, el tercer O-T y el cuarto U-Z.
- Para insertar o recuperar un objeto, usa el mapa apropiado en función del personaje de inicio del objeto.
Agregar una Mapa Ordenado
-- Inicialice el servicio de almacenamiento de memoria
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Crea tus cubos de mapa clasificados
local sm_AtoG = MemoryStoreService:GetSortedMap("AtoG")
local sm_HtoM = MemoryStoreService:GetSortedMap("HtoM")
local sm_NtoT = MemoryStoreService:GetSortedMap("NtoT")
local sm_UtoZ = MemoryStoreService:GetSortedMap("UtoZ")
-- Función de ayudante para recuperar el cubo correcto de la llave de artículo
local function getSortedMapBucket(itemKey)
if (itemKey >= "a" and itemKey < "h") then
return sm_AtoG
elseif (itemKey < "n") then
return sm_HtoM
elseif (itemKey < "u") then
return sm_NtoT
else
return sm_UtoZ
end
end
-- Inicialice los nombres de los jugadores con el valor predeterminado de 0
for _, player in game:GetService("Players"):GetPlayers() do
local bucket = getSortedMapBucket(player)
bucket:SetAsync(player, 0, 600)
end
-- Recuperar el valor de un jugador
local player = "myPlayer"
local bucket = getSortedMapBucket(player)
local playerScore = bucket:GetAsync(player)
print(playerScore)
Agregar una cola
Agregar, leer y eliminar solo se agrega, lee y elimina cuando se trata de una tabla clasificada. Aunque desea que la solicitud se distribuya entre múltiples subejes, agrega, lee y elimina solo cuando se trata de la parte delantera o trasera de la cola.
Una solución es usar una cola giratoria, lo que significa crear múltiples colas y rotar entre ellas cuando agregas o lees un objeto:
Crea varias colas y agrégalas a un matriz/lista.
Cree dos puntos locales. Uno representa la cola que desea leer y eliminar los elementos. El otro representa la cola que desea agregar los elementos:
- Para operaciones de lectura, calcula el número de artículos que necesitas de cada cola, así como dónde mover el puntero de lectura.
- Para eliminar operaciones, envía los ID de la lectura a cada cola.
- Para agregar operaciones, agregue a la cola en el punto de agregación y aumente el punto de agregación.
Agregar una cola
-- Inicialice el servicio de almacenamiento de memoria
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Crear tus colas
local q1 = MemoryStoreService:GetQueue("q1")
local q2 = MemoryStoreService:GetQueue("q2")
local q3 = MemoryStoreService:GetQueue("q3")
local q4 = MemoryStoreService:GetQueue("q4")
-- Pon las colas en un array
local queueArr = { q1, q2, q3, q4 }
-- Cree dos punteros que representen los índices de la lectura y agregue colas
local readIndex = 1
local addIndex = 1
-- Crea una función local que actualiza los índices adecuadamente
local function rotateIndex(index, n)
return (index + n - 1) % 4 + 1
end
-- Crea una función local que lee n artículos de la cola
local function readFromQueue(count, allOrNothing, waitTimeout)
local endIndex = count % 4
local countPerQueue = count // 4
local items = {}
local ids = {}
-- iterar a través de cada cola
for i = 1, 4, 1 do
-- determine si esta cola leerá un objetoextra
local diff = i - readIndex
if diff < 0 then
diff += 4
end
local queue = queueArr[i]
-- leer artículos de cada cola
-- +1 artículos si coincide con criterios de lectura adicional
if diff < endIndex then
items[i], ids[i] = queue:ReadAsync(countPerQueue + 1, allOrNothing,waitTimeout)
else
items[i], ids[i] = queue:ReadAsync(countPerQueue, allOrNothing,waitTimeout)
end
end
readIndex = rotateIndex(readIndex, count)
return items, ids
end
-- Crea una función local que elimina n elementos de la cola
local function removeFromQueue(ids)
for i = 1, 4, 1 do
local queue = queueArr[readIndex]
queue:RemoveAsync(ids[i])
end
end
-- Crea una función local que agrega un artículo a la cola
local function addToQueue(itemKey, expiration, priority)
local queue = queueArr[readIndex]
queue:AddAsync(itemKey, expiration, priority)
addIndex = rotateIndex(addIndex, 1)
end
-- ¡Escriba algunos códigos!
for _, player in game:GetService("Players"):GetPlayers() do
addToQueue(player, 600, 0)
end
local players, ids = readFromQueue(20, true, -1)
removeFromQueue(ids)
Mapas de hash
Las tablas de hash no tienen límites de memoria o de contador de artículos individuales y se fragmentan automáticamente, pero aún puede encontrar un rendimiento limitado si los usa mal.
Por ejemplo, considere una experiencia con un mapa de datos del juego, almacenado como el valor de una sola llave llamada metadata . Si este método de datos contiene un objeto basado en el subconjunto de objetos con información, como el ID de lugar, el número de jugadores y más, cada vez que se necesite el método de datos, no tiene más remedio que llamar a GetAsync("metadata") y recuperar
En lugar de almacenar todo el metadato como un objeto de clave única, mejor aprovechar cada campo como su propia clave para que el mapa de caché pueda aprovecharse de la optimización automática. Si necesita separación entre el metadato y el resto del mapa de caché, agregue un prefijo de nombre (por ejemplo, metadata_user_count en lugar de simplemente user_count).