summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-11-19 09:48:12 +0100
committerantirez <antirez@gmail.com>2013-11-21 15:22:07 +0100
commita52909c5f21fc81b8aeff3e67eea96126f911228 (patch)
tree28bfc35e5af158d9e1e773709a8ec3470e823092
parent8c3e197040cb735b727cb3d0da8fc565ac3b0bc8 (diff)
downloadredis-a52909c5f21fc81b8aeff3e67eea96126f911228.tar.gz
Sentinel: CONFIG REWRITE support for Sentinel config.
-rw-r--r--src/config.c5
-rw-r--r--src/redis.h2
-rw-r--r--src/sentinel.c109
3 files changed, 112 insertions, 4 deletions
diff --git a/src/config.c b/src/config.c
index 235d0dc83..29e1893b6 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1110,6 +1110,10 @@ int dictSdsKeyCompare(void *privdata, const void *key1, const void *key2);
void dictSdsDestructor(void *privdata, void *val);
void dictListDestructor(void *privdata, void *val);
+/* Sentinel config rewriting is implemented inside sentinel.c by
+ * rewriteConfigSentinelOption(). */
+void rewriteConfigSentinelOption(struct rewriteConfigState *state);
+
dictType optionToLineDictType = {
dictSdsHash, /* hash function */
NULL, /* key dup */
@@ -1680,6 +1684,7 @@ int rewriteConfig(char *path) {
rewriteConfigClientoutputbufferlimitOption(state);
rewriteConfigNumericalOption(state,"hz",server.hz,REDIS_DEFAULT_HZ);
rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,REDIS_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC);
+ if (server.sentinel_mode) rewriteConfigSentinelOption(state);
/* Step 3: remove all the orphaned lines in the old file, that is, lines
* that were used by a config option and are no longer used, like in case
diff --git a/src/redis.h b/src/redis.h
index 3a0e9df00..015d82c4d 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -1144,6 +1144,8 @@ sds keyspaceEventsFlagsToString(int flags);
void loadServerConfig(char *filename, char *options);
void appendServerSaveParams(time_t seconds, int changes);
void resetServerSaveParams();
+struct rewriteConfigState; /* Forward declaration to export API. */
+void rewriteConfigRewriteLine(struct rewriteConfigState *state, char *option, sds line, int force);
/* db.c -- Keyspace access API */
int removeExpire(redisDb *db, robj *key);
diff --git a/src/sentinel.c b/src/sentinel.c
index 5bd562acb..e71486f27 100644
--- a/src/sentinel.c
+++ b/src/sentinel.c
@@ -1305,10 +1305,10 @@ char *sentinelHandleConfiguration(char **argv, int argc) {
ri->config_epoch = strtoull(argv[2],NULL,10);
if (ri->config_epoch > sentinel.current_epoch)
sentinel.current_epoch = ri->config_epoch;
- } else if (!strcasecmp(argv[0],"slave") && argc == 3) {
+ } else if (!strcasecmp(argv[0],"known-slave") && argc == 3) {
sentinelRedisInstance *slave;
- /* slave <name> <ip> <port> */
+ /* known-slave <name> <ip> <port> */
ri = sentinelGetMasterByName(argv[1]);
if (!ri) return "No such master with specified name.";
if ((slave = createSentinelRedisInstance(NULL,SRI_SLAVE,argv[2],
@@ -1316,10 +1316,10 @@ char *sentinelHandleConfiguration(char **argv, int argc) {
{
return "Wrong hostname or port for slave.";
}
- } else if (!strcasecmp(argv[0],"sentinel") && argc == 3) {
+ } else if (!strcasecmp(argv[0],"known-sentinel") && argc == 3) {
sentinelRedisInstance *si;
- /* sentinel <name> <ip> <port> */
+ /* known-sentinel <name> <ip> <port> */
ri = sentinelGetMasterByName(argv[1]);
if (!ri) return "No such master with specified name.";
if ((si = createSentinelRedisInstance(NULL,SRI_SENTINEL,argv[2],
@@ -1333,6 +1333,107 @@ char *sentinelHandleConfiguration(char **argv, int argc) {
return NULL;
}
+/* Implements CONFIG REWRITE for "sentinel" option.
+ * This is used not just to rewrite the configuration given by the user
+ * (the configured masters) but also in order to retain the state of
+ * Sentinel across restarts: config epoch of masters, associated slaves
+ * and sentinel instances, and so forth. */
+void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
+ dictIterator *di, *di2;
+ dictEntry *de;
+
+ /* For every master emit a "sentinel monitor" config entry. */
+ di = dictGetIterator(sentinel.masters);
+ while((de = dictNext(di)) != NULL) {
+ sentinelRedisInstance *master, *ri;
+ sds line;
+
+ /* sentinel monitor */
+ master = dictGetVal(de);
+ line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d",
+ master->name, master->addr->ip, master->addr->port,
+ master->quorum);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+
+ /* sentinel down-after-milliseconds */
+ if (master->down_after_period != SENTINEL_DEFAULT_DOWN_AFTER) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel down-after-milliseconds %s %ld",
+ master->name, (long) master->down_after_period);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel failover-timeout */
+ if (master->failover_timeout != SENTINEL_DEFAULT_FAILOVER_TIMEOUT) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel failover-timeout %s %ld",
+ master->name, (long) master->failover_timeout);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel parallel-syncs */
+ if (master->parallel_syncs != SENTINEL_DEFAULT_PARALLEL_SYNCS) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel parallel-syncs %s %d",
+ master->name, master->parallel_syncs);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel notification-script */
+ if (master->notification_script) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel notification-script %s %s",
+ master->name, master->notification_script);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel client-reconfig-script */
+ if (master->client_reconfig_script) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel client-reconfig-script %s %s",
+ master->name, master->client_reconfig_script);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel auth-pass */
+ if (master->auth_pass) {
+ line = sdscatprintf(sdsempty(),
+ "sentinel auth-pass %s %s",
+ master->name, master->auth_pass);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+
+ /* sentinel config-epoch */
+ line = sdscatprintf(sdsempty(),
+ "sentinel config-epoch %s %llu",
+ master->name, (unsigned long long) master->config_epoch);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+
+ /* sentinel known-slave */
+ di2 = dictGetIterator(master->slaves);
+ while((de = dictNext(di)) != NULL) {
+ ri = dictGetVal(de);
+ line = sdscatprintf(sdsempty(),
+ "sentinel known-slave %s %s %d",
+ master->name, ri->addr->ip, ri->addr->port);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+ dictReleaseIterator(di2);
+
+ /* sentinel known-sentinel */
+ di2 = dictGetIterator(master->sentinels);
+ while((de = dictNext(di)) != NULL) {
+ ri = dictGetVal(de);
+ line = sdscatprintf(sdsempty(),
+ "sentinel known-sentinel %s %s %d",
+ master->name, ri->addr->ip, ri->addr->port);
+ rewriteConfigRewriteLine(state,"sentinel",line,1);
+ }
+ dictReleaseIterator(di2);
+ }
+ dictReleaseIterator(di);
+}
+
/* ====================== hiredis connection handling ======================= */
/* Completely disconnect an hiredis link from an instance. */