Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,8 @@ test/tmp/
# BenchmarkDotNet Results
BenchmarkDotNet.Artifacts/

# PerfView Results
*PerfView*.*

# Helm chart artifacts
.cr-release-packages/
4 changes: 3 additions & 1 deletion libs/client/CompletionEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

namespace Garnet.client
{
// This structure uses a SemaphoreSlim as if it were a ManualResetEventSlim, because MRES does not support async waiting.
// This structure uses a SemaphoreSlim as if it were an AutoResetEvent, because ARE does not support async waiting.
internal struct CompletionEvent : IDisposable
{
private SemaphoreSlim semaphore;

public override string ToString() => semaphore?.ToString();

internal void Initialize() => this.semaphore = new SemaphoreSlim(0);

internal void Set()
Expand Down
9 changes: 3 additions & 6 deletions libs/cluster/Server/Replication/PrimaryOps/AofTaskStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ internal sealed class AofTaskStore : IDisposable
readonly ClusterProvider clusterProvider;
readonly ILogger logger;
readonly int logPageSizeBits, logPageSizeMask;
readonly long TruncateLagAddress;

AofSyncTaskInfo[] tasks;
int numTasks;
Expand All @@ -42,7 +41,6 @@ public AofTaskStore(ClusterProvider clusterProvider, int initialSize = 1, ILogge
logPageSizeMask = logPageSize - 1;
if (clusterProvider.serverOptions.FastAofTruncate)
clusterProvider.storeWrapper.appendOnlyFile.SafeTailShiftCallback = SafeTailShiftCallback;
TruncateLagAddress = clusterProvider.storeWrapper.appendOnlyFile.UnsafeGetReadOnlyAddressLagOffset() - 2 * logPageSize;
}
TruncatedUntil = 0;
}
Expand All @@ -56,10 +54,9 @@ internal void SafeTailShiftCallback(long oldTailAddress, long newTailAddress)
// Call truncate only once per page
if (oldPage != newPage)
{
// Truncate 2 pages after ReadOnly mark, so that we have sufficient time to shift begin before we flush
long truncateUntilAddress = (newTailAddress & ~logPageSizeMask) - TruncateLagAddress;
// Do not truncate beyond new tail (to handle corner cases)
if (truncateUntilAddress > newTailAddress) truncateUntilAddress = newTailAddress;
// Truncate 2 pages above ReadOnly mark, so that we have sufficient time to shift begin before we flush.
// Make sure this is page-aligned, in case we go to a non-page-aligned ReadOnlyAddress.
var truncateUntilAddress = clusterProvider.storeWrapper.appendOnlyFile.UnsafeGetReadOnlyAddressAbove(newTailAddress, numPagesAbove: 2);
if (truncateUntilAddress > 0)
SafeTruncateAof(truncateUntilAddress);
}
Expand Down
36 changes: 18 additions & 18 deletions libs/host/Configuration/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,17 @@ internal sealed class Options : ICloneable
public ClusterPreferredEndpointType ClusterPreferredEndpointType { get; set; }

[MemorySizeValidation]
[Option('m', "memory", Required = false, HelpText = "Total log memory used in bytes (rounds down to power of 2)")]
public string MemorySize { get; set; }
[Option('m', "memory", Required = false, HelpText = "Total main-log memory (inline and heap) to use, in bytes. Does not need to be a power of 2")]
public string LogMemorySize { get; set; }

[MemorySizeValidation]
[Option('p', "page", Required = false, HelpText = "Size of each page in bytes (rounds down to power of 2)")]
[Option('p', "page", Required = false, HelpText = "Size of each main-log page in bytes (rounds down to power of 2).")]
public string PageSize { get; set; }

[IntRangeValidation(0, MemoryUtils.ArrayMaxLength)]
[Option("pagecount", Required = false, HelpText = "Number of main-log pages (rounds down to power of 2). This allows specifying less pages initially than LogMemorySize divided by PageSize.")]
public int PageCount { get; set; }

[MemorySizeValidation]
[Option('s', "segment", Required = false, HelpText = "Size of each main-log segment in bytes on disk (rounds down to power of 2)")]
public string SegmentSize { get; set; }
Expand All @@ -77,11 +81,11 @@ internal sealed class Options : ICloneable

[MemorySizeValidation]
[Option('i', "index", Required = false, HelpText = "Start size of hash index in bytes (rounds down to power of 2)")]
public string IndexSize { get; set; }
public string IndexMemorySize { get; set; }

[MemorySizeValidation(false)]
[Option("index-max-size", Required = false, HelpText = "Max size of hash index in bytes (rounds down to power of 2)")]
public string IndexMaxSize { get; set; }
public string IndexMaxMemorySize { get; set; }

[PercentageValidation(false)]
[Option("mutable-percent", Required = false, HelpText = "Percentage of log memory that is kept mutable")]
Expand All @@ -92,20 +96,16 @@ internal sealed class Options : ICloneable
public bool? EnableReadCache { get; set; }

[MemorySizeValidation]
[Option("readcache-memory", Required = false, HelpText = "Total read cache log memory used in bytes (rounds down to power of 2)")]
[Option("readcache-memory", Required = false, HelpText = "Total readcache-log memory (inline and heap) to use if readcache is enabled, in bytes. Does not need to be a power of 2")]
public string ReadCacheMemorySize { get; set; }

[MemorySizeValidation]
[Option("readcache-page", Required = false, HelpText = "Size of each read cache page in bytes (rounds down to power of 2)")]
public string ReadCachePageSize { get; set; }

[MemorySizeValidation(false)]
[Option("heap-memory", Required = false, HelpText = "Heap memory size in bytes (Sum of size taken up by all object instances in the heap)")]
public string HeapMemorySize { get; set; }

[MemorySizeValidation(false)]
[Option("readcache-heap-memory", Required = false, HelpText = "Read cache heap memory size in bytes (Sum of size taken up by all object instances in the heap)")]
public string ReadCacheHeapMemorySize { get; set; }
[IntRangeValidation(0, MemoryUtils.ArrayMaxLength)]
[Option("readcache-pagecount", Required = false, HelpText = "Number of readcache-log pages (rounds down to power of 2). This allows specifying less pages initially than ReadCacheMemorySize divided by ReadCachePageSize.")]
public int ReadCachePageCount { get; set; }

[OptionValidation]
[Option("storage-tier", Required = false, HelpText = "Enable tiering of records (hybrid log) to storage, to support a larger-than-memory store. Use --logdir to specify storage directory.")]
Expand Down Expand Up @@ -790,18 +790,18 @@ public GarnetServerOptions GetServerOptions(ILogger logger = null)
ClusterAnnounceEndpoint = clusterAnnounceEndpoint?[0],
ClusterAnnounceHostname = ClusterAnnounceHostname,
ClusterPreferredEndpointType = ClusterPreferredEndpointType,
MemorySize = MemorySize,
LogMemorySize = LogMemorySize,
PageSize = PageSize,
PageCount = PageCount,
SegmentSize = SegmentSize,
ObjectLogSegmentSize = ObjectLogSegmentSize,
IndexSize = IndexSize,
IndexMaxSize = IndexMaxSize,
IndexMemorySize = IndexMemorySize,
IndexMaxMemorySize = IndexMaxMemorySize,
MutablePercent = MutablePercent,
EnableReadCache = EnableReadCache.GetValueOrDefault(),
ReadCacheMemorySize = ReadCacheMemorySize,
ReadCachePageSize = ReadCachePageSize,
HeapMemorySize = HeapMemorySize,
ReadCacheHeapMemorySize = ReadCacheHeapMemorySize,
ReadCachePageCount = ReadCachePageCount,
EnableStorageTier = enableStorageTier,
CopyReadsToTail = CopyReadsToTail.GetValueOrDefault(),
LogDir = logDir,
Expand Down
2 changes: 1 addition & 1 deletion libs/host/Configuration/Redis/RedisOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal class RedisOptions
[RedisOption("port", nameof(Options.Port))]
public Option<int> Port { get; set; }

[RedisOption("maxmemory", nameof(Options.MemorySize))]
[RedisOption("maxmemory", nameof(Options.LogMemorySize))]
public Option<string> MaxMemory { get; set; }

[RedisOption("logfile", nameof(Options.FileLogger))]
Expand Down
13 changes: 4 additions & 9 deletions libs/host/GarnetServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ private TsavoriteKV<StoreFunctions, StoreAllocator> CreateStore(int dbId, IClust
epoch = new LightEpoch();
stateMachineDriver = new StateMachineDriver(epoch, loggerFactory?.CreateLogger($"StateMachineDriver"));

kvSettings = opts.GetSettings(loggerFactory, epoch, stateMachineDriver, out logFactory, out var heapMemorySize, out var readCacheHeapMemorySize);
kvSettings = opts.GetSettings(loggerFactory, epoch, stateMachineDriver, out logFactory);

// Run checkpoint on its own thread to control p99
kvSettings.ThrottleCheckpointFlushDelayMs = opts.CheckpointThrottleFlushDelayMs;
Expand All @@ -343,9 +343,8 @@ private TsavoriteKV<StoreFunctions, StoreAllocator> CreateStore(int dbId, IClust
() => new GarnetObjectSerializer(customCommandManager))
, (allocatorSettings, storeFunctions) => new(allocatorSettings, storeFunctions));

if (heapMemorySize > 0 || readCacheHeapMemorySize > 0)
sizeTracker = new CacheSizeTracker(store, heapMemorySize, readCacheHeapMemorySize, this.loggerFactory);

if (kvSettings.LogMemorySize > 0 || kvSettings.ReadCacheMemorySize > 0)
sizeTracker = new CacheSizeTracker(store, kvSettings.LogMemorySize, kvSettings.ReadCacheMemorySize, this.loggerFactory);
return store;
}

Expand Down Expand Up @@ -428,14 +427,10 @@ private static void DeleteDirectory(string path)
try
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}

Directory.Delete(path, true);
}
catch (Exception ex) when (ex is IOException ||
ex is UnauthorizedAccessException)
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
try
{
Expand Down
22 changes: 11 additions & 11 deletions libs/host/defaults.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,41 @@
/* Determines the endpoint type to be advertised to other nodes. (value options: ip, hostname, unknown-endpoint) */
"ClusterPreferredEndpointType" : "ip",

/* Total log memory used in bytes (rounds down to power of 2) */
"MemorySize" : "16g",
/* Total main-log memory (inline and heap) to use, in bytes. Does not need to be a power of 2 */
"LogMemorySize" : "16g",

/* Size of each page in bytes (rounds down to power of 2) */
/* Size of each main-log page in bytes (rounds down to power of 2). */
"PageSize" : "32m",

/* Number of main-log pages (rounds down to power of 2). This allows specifying less pages initially than LogMemorySize divided by PageSize. */
"PageCount" : 0,

/* Size of each main-log segment in bytes on disk (rounds down to power of 2) */
"SegmentSize" : "1g",

/* Size of each object-log segment in bytes on disk (rounds down to power of 2) */
"ObjectLogSegmentSize" : "1g",

/* Start size of hash index in bytes (rounds down to power of 2) */
"IndexSize" : "128m",
"IndexMemorySize" : "128m",

/* Max size of hash index in bytes (rounds down to power of 2) */
"IndexMaxSize": "",
"IndexMaxMemorySize": "",

/* Percentage of log memory that is kept mutable */
"MutablePercent" : 90,

/* Enable read cache for faster access to on-disk records */
"EnableReadCache" : false,

/* Total read cache log memory used in bytes (rounds down to power of 2) */
/* Total readcache-log memory (inline and heap) to use if readcache is enabled, in bytes. Does not need to be a power of 2 */
"ReadCacheMemorySize" : "1g",

/* Size of each read cache page in bytes (rounds down to power of 2) */
"ReadCachePageSize" : "32m",

/* Heap memory size in bytes (Sum of size taken up by all object instances in the heap) */
"HeapMemorySize" : "",

/* Read cache heap memory size in bytes (Sum of size taken up by all object instances in the heap) */
"ReadCacheHeapMemorySize" : "",
/* Number of readcache-log pages (rounds down to power of 2). This allows specifying less pages initially than ReadCacheMemorySize divided by ReadCachePageSize. */
"ReadCachePageCount" : 0,

/* Enable tiering of records (hybrid log) to storage, to support a larger-than-memory store. Use --logdir to specify storage directory. */
"EnableStorageTier" : false,
Expand Down
4 changes: 2 additions & 2 deletions libs/server/Databases/DatabaseManagerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private static bool ShouldCreateMultipleDatabaseManager(GarnetServerOptions serv
{
// Check if there are multiple databases to recover from checkpoint
var checkpointParentDir = serverOptions.StoreCheckpointBaseDirectory;
var checkpointDirBaseName = serverOptions.GetCheckpointDirectoryName(0);
var checkpointDirBaseName = GarnetServerOptions.GetCheckpointDirectoryName(0);

if (MultiDatabaseManager.TryGetSavedDatabaseIds(checkpointParentDir, checkpointDirBaseName,
out var dbIds) && dbIds.Any(id => id != 0))
Expand All @@ -48,7 +48,7 @@ private static bool ShouldCreateMultipleDatabaseManager(GarnetServerOptions serv
if (serverOptions.EnableAOF)
{
var aofParentDir = serverOptions.AppendOnlyFileBaseDirectory;
var aofDirBaseName = serverOptions.GetAppendOnlyFileDirectoryName(0);
var aofDirBaseName = GarnetServerOptions.GetAppendOnlyFileDirectoryName(0);

if (MultiDatabaseManager.TryGetSavedDatabaseIds(aofParentDir, aofDirBaseName,
out dbIds) && dbIds.Any(id => id != 0))
Expand Down
6 changes: 4 additions & 2 deletions libs/server/Databases/MultiDatabaseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public override void RecoverCheckpoint(bool replicaRecover = false, bool recover
$"Unexpected call to {nameof(MultiDatabaseManager)}.{nameof(RecoverCheckpoint)} with {nameof(replicaRecover)} == true.");

var checkpointParentDir = StoreWrapper.serverOptions.StoreCheckpointBaseDirectory;
var checkpointDirBaseName = StoreWrapper.serverOptions.GetCheckpointDirectoryName(0);
var checkpointDirBaseName = GarnetServerOptions.GetCheckpointDirectoryName(0);

int[] dbIdsToRecover;
try
Expand Down Expand Up @@ -403,7 +403,7 @@ public override async Task WaitForCommitToAofAsync(CancellationToken token = def
public override void RecoverAOF()
{
var aofParentDir = StoreWrapper.serverOptions.AppendOnlyFileBaseDirectory;
var aofDirBaseName = StoreWrapper.serverOptions.GetAppendOnlyFileDirectoryName(0);
var aofDirBaseName = GarnetServerOptions.GetAppendOnlyFileDirectoryName(0);

int[] dbIdsToRecover;
try
Expand Down Expand Up @@ -947,12 +947,14 @@ private void CopyDatabases(IDatabaseManager src, bool enableAof)
{
case SingleDatabaseManager sdbm:
var defaultDbCopy = new GarnetDatabase(0, sdbm.DefaultDatabase, enableAof);
sizeTrackersStarted = sdbm.SizeTracker?.IsStarted ?? false;
TryAddDatabase(0, defaultDbCopy);
return;
case MultiDatabaseManager mdbm:
var activeDbIdsMapSize = mdbm.activeDbIds.ActualSize;
var activeDbIdsMapSnapshot = mdbm.activeDbIds.Map;
var databasesMapSnapshot = mdbm.databases.Map;
sizeTrackersStarted = mdbm.sizeTrackersStarted;

for (var i = 0; i < activeDbIdsMapSize; i++)
{
Expand Down
11 changes: 1 addition & 10 deletions libs/server/GarnetDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT license.

using System;
using System.Threading;
using Garnet.common;
using Tsavorite.core;

Expand Down Expand Up @@ -157,15 +156,7 @@ public void Dispose()
kvSettings?.LogDevice?.Dispose();
kvSettings?.ObjectLogDevice?.Dispose();

if (SizeTracker != null)
{
// If tracker has previously started, wait for it to stop
if (!SizeTracker.TryPreventStart())
{
while (!SizeTracker.Stopped)
Thread.Yield();
}
}
SizeTracker?.Stop();
}
}
}
Loading
Loading