From 1d7a217a04be78fae331357e3b87dbafc9f22dab Mon Sep 17 00:00:00 2001 From: michalbiesek Date: Fri, 19 Jun 2020 12:41:50 +0200 Subject: [PATCH] Add hashtable-on-dram option - set to no to keep expected dram-pmem ratio for small object size e.g. 32 bytes for 1:16 ratio - restore generic zfree mechanism in dict module - Hashtable is initialized before reading config - so it could be on dram or pmem, despite the selected hashtable-on-dram option Co-authored-by: jschmieg --- redis.conf | 3 +++ src/config.c | 6 ++++++ src/dict.c | 11 ++++++++--- src/dict.h | 1 + src/server.c | 2 ++ src/server.h | 1 + 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/redis.conf b/redis.conf index 9e07fc55502..3178f724067 100644 --- a/redis.conf +++ b/redis.conf @@ -1122,3 +1122,6 @@ dynamic-threshold-max 10000 # DRAM/PMEM ratio period measured in miliseconds memory-ratio-check-period 100 + +# Keep hashtable structure always on DRAM +hashtable-on-dram yes diff --git a/src/config.c b/src/config.c index 7dd91695854..72c1e8516fc 100644 --- a/src/config.c +++ b/src/config.c @@ -335,6 +335,10 @@ void loadServerConfigFromString(char *config) { if (server.ratio_check_period < 1) { err = "Invalid number of memory ratio check period"; goto loaderr; } + } else if (!strcasecmp(argv[0],"hashtable-on-dram") && argc == 2) { + if ((server.hashtable_on_dram = yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) { server.maxmemory = memtoll(argv[1],NULL); } else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) { @@ -1210,6 +1214,8 @@ void configGetCommand(client *c) { server.aof_rewrite_incremental_fsync); config_get_bool_field("aof-load-truncated", server.aof_load_truncated); + config_get_bool_field("hashtable-on-dram", + server.hashtable_on_dram); /* Enum values */ config_get_enum_field("maxmemory-policy", diff --git a/src/dict.c b/src/dict.c index 8b92462c498..f6ed4c110d5 100644 --- a/src/dict.c +++ b/src/dict.c @@ -57,6 +57,7 @@ * the number of elements and the buckets > dict_force_resize_ratio. */ static int dict_can_resize = 1; static unsigned int dict_force_resize_ratio = 5; +static int dict_always_on_dram = 1; /* -------------------------- private prototypes ---------------------------- */ @@ -89,6 +90,10 @@ uint32_t dictGetHashFunctionSeed(void) { return dict_hash_function_seed; } +void dictSetAllocPolicy(int policy) { + dict_always_on_dram = policy; +} + /* MurmurHash2, by Austin Appleby * Note - This code makes a few assumptions about how your machine behaves - * 1. We can read a 4-byte value from any address without crashing @@ -217,7 +222,7 @@ int dictExpand(dict *d, unsigned long size) /* Allocate the new hash table and initialize all pointers to NULL */ n.size = realsize; n.sizemask = realsize-1; - n.table = zcalloc_dram(realsize*sizeof(dictEntry*)); + n.table = (dict_always_on_dram) ? zcalloc_dram(realsize*sizeof(dictEntry*)) : zcalloc(realsize*sizeof(dictEntry*)); n.used = 0; /* Is this the first initialization? If so it's not really a rehashing @@ -276,7 +281,7 @@ int dictRehash(dict *d, int n) { /* Check if we already rehashed the whole table... */ if (d->ht[0].used == 0) { - zfree_dram(d->ht[0].table); + zfree(d->ht[0].table); d->ht[0] = d->ht[1]; _dictReset(&d->ht[1]); d->rehashidx = -1; @@ -475,7 +480,7 @@ int _dictClear(dict *d, dictht *ht, void(callback)(void *)) { } } /* Free the table and the allocated cache structure */ - zfree_dram(ht->table); + zfree(ht->table); /* Re-initialize the table */ _dictReset(ht); return DICT_OK; /* never fails */ diff --git a/src/dict.h b/src/dict.h index e31daee2a05..bddb7f71572 100644 --- a/src/dict.h +++ b/src/dict.h @@ -174,6 +174,7 @@ void dictDisableResize(void); int dictRehash(dict *d, int n); int dictRehashMilliseconds(dict *d, int ms); void dictSetHashFunctionSeed(unsigned int initval); +void dictSetAllocPolicy(int policy); unsigned int dictGetHashFunctionSeed(void); unsigned long dictScan(dict *d, unsigned long v, dictScanFunction *fn, void *privdata); diff --git a/src/server.c b/src/server.c index bd1164b0cbe..1f17bac743b 100644 --- a/src/server.c +++ b/src/server.c @@ -1520,6 +1520,7 @@ void initServerConfig(void) { server.activerehashing = CONFIG_DEFAULT_ACTIVE_REHASHING; server.notify_keyspace_events = 0; server.maxclients = CONFIG_DEFAULT_MAX_CLIENTS; + server.hashtable_on_dram = 1; server.bpop_blocked_clients = 0; server.maxmemory = CONFIG_DEFAULT_MAXMEMORY; server.maxmemory_policy = CONFIG_DEFAULT_MAXMEMORY_POLICY; @@ -2015,6 +2016,7 @@ void initServer(void) { slowlogInit(); latencyMonitorInit(); pmemThresholdInit(); + dictSetAllocPolicy(server.hashtable_on_dram); bioInit(); } diff --git a/src/server.h b/src/server.h index 7ae4f30947d..4d0b9e69a71 100644 --- a/src/server.h +++ b/src/server.h @@ -933,6 +933,7 @@ struct redisServer { ratioDramPmemConfig dram_pmem_ratio; /* DRAM/Persistent Memory ratio */ double target_pmem_dram_ratio; /* Target PMEM/DRAM ratio */ int ratio_check_period; /* Period of checking ratio in Cron*/ + int hashtable_on_dram; /* Keep hashtable always on DRAM */ /* Blocked clients */ unsigned int bpop_blocked_clients; /* Number of clients blocked by lists */ list *unblocked_clients; /* list of clients to unblock before next loop */