From bd8cdb3244d058ad062610c8dc914374b52dd1e6 Mon Sep 17 00:00:00 2001
From: liusuyi <13324259@qq.com>
Date: 星期一, 23 十月 2023 20:33:37 +0800
Subject: [PATCH] 增加redis和流媒体服务外部程序 增加流媒体日志
---
server/mediamtx/LICENSE | 26
server/redis/redis-server.pdb | 0
server/redis/dump.rdb | 0
server/redis/redis.windows.conf | 1048 ++++++++++++++++++++
server/redis/redis-check-aof.pdb | 0
server/redis/Windows Service Documentation.docx | 0
server/redis/redis-check-aof.exe | 0
server/redis/redis-cli.pdb | 0
server/redis/redis-server.exe | 0
server/redis/redis-desktop-manager-0.9.3.817.exe | 0
server/redis/Redis on Windows.docx | 0
server/redis/redis-cli.exe | 0
server/redis/redis-benchmark.pdb | 0
server/mediamtx/ffmpeg.exe | 0
server/redis/Redis on Windows Release Notes.docx | 0
server/mediamtx/mediamtx.exe | 0
server/redis/redis-benchmark.exe | 0
ard-work/src/main/java/com/ruoyi/media/service/impl/MediaServiceImpl.java | 93 +
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java | 198 ++-
ruoyi-admin/src/main/resources/logback.xml | 17
server/redis/EventLog.dll | 0
server/redis/redis.windows-service.conf | 1048 ++++++++++++++++++++
server/mediamtx/mediamtx.yml | 556 +++++++++++
23 files changed, 2,849 insertions(+), 137 deletions(-)
diff --git a/ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java b/ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java
index ccf35e4..9ebe065 100644
--- a/ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java
+++ b/ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java
@@ -75,112 +75,116 @@
*/
@Override
public void login(ArdCameras camera) {
- // 鍒濆鍖�
- if (!hCNetSDK.NET_DVR_Init()) {
- log.error("SDK鍒濆鍖栧け璐�");
- }
- //鎵撳嵃娴峰悍sdk鏃ュ織
- if (Platform.isWindows()) {
- String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator;
- hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true);
- } else {
- hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true);
- }
- String m_sDeviceIP = camera.getIp();
- String m_sUsername = camera.getUsername();
- String m_sPassword = camera.getPassword();
- short m_sPort = camera.getPort().shortValue();
- //璁剧疆杩炴帴鏃堕棿涓庨噸杩炴椂闂�
- hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
- hCNetSDK.NET_DVR_SetReconnect(5000, true);
- //璁惧淇℃伅, 杈撳嚭鍙傛暟
- HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
- HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
-
- // 娉ㄥ唽璁惧-鐧诲綍鍙傛暟锛屽寘鎷澶囧湴鍧�銆佺櫥褰曠敤鎴枫�佸瘑鐮佺瓑
- m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
- System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
- m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
- System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
- m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
- System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
- m_strLoginInfo.wPort = m_sPort;
- m_strLoginInfo.byVerifyMode = 0;
- m_strLoginInfo.byLoginMode = 0;
- //鏄惁寮傛鐧诲綍锛�0- 鍚︼紝1- 鏄� windowsSDK閲屾槸true鍜宖alse
- m_strLoginInfo.bUseAsynLogin = false;
- m_strLoginInfo.write();
- //鍚屾鐧诲綍
- int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
- if (lUserID < 0) {
- int errorCode = hCNetSDK.NET_DVR_GetLastError();
- log.debug(camera.getIp() + ":" + camera.getPort() + "鐧诲綍澶辫触,閿欒鐮侊細"+errorCode);
- camera.setChanNum(0);
- camera.setLoginId(-1);
- camera.setState("0");
- } else {
- if (fExceptionCallBack == null) {
- fExceptionCallBack = new ExceptionCallBack();//寮傚父鍥炶皟
- //璁剧疆寮傚父鍥炶皟鍑芥暟(鍙湪鍥炶皟鍑芥暟涓幏鍙栬澶囦笂涓嬬嚎鐘舵�佺瓑)
- if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, null)) {
- log.info("Set fExceptionCallBack function fail");
- return;
- } else {
- log.info("Set fExceptionCallBack function successfully!");
- }
+ try {
+ // 鍒濆鍖�
+ if (!hCNetSDK.NET_DVR_Init()) {
+ log.error("SDK鍒濆鍖栧け璐�");
}
-
- if (GlobalVariable.loginMap.containsKey(camera.getId())) {
- GlobalVariable.loginMap.remove(camera.getId());
+ //鎵撳嵃娴峰悍sdk鏃ュ織
+ if (Platform.isWindows()) {
+ String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator;
+ hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true);
+ } else {
+ hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true);
}
- //鍒犻櫎绠$悊閫氶亾
- ardChannelService.deleteArdChannelByDeviceId(camera.getId());
- GlobalVariable.loginMap.put(camera.getId(), lUserID);
- GlobalVariable.loginCameraMap.put(lUserID,camera);
+ String m_sDeviceIP = camera.getIp();
+ String m_sUsername = camera.getUsername();
+ String m_sPassword = camera.getPassword();
+ short m_sPort = camera.getPort().shortValue();
+ //璁剧疆杩炴帴鏃堕棿涓庨噸杩炴椂闂�
+ hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
+ hCNetSDK.NET_DVR_SetReconnect(5000, true);
+ //璁惧淇℃伅, 杈撳嚭鍙傛暟
+ HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
+ HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
- log.debug("Login Success [ " + camera.getIp() + ":" + camera.getPort() + " ]");
- camera.setLoginId(lUserID);
- camera.setState("1");
- camera.setChanNum((int) m_strDeviceInfo.struDeviceV30.byChanNum);
- camera.setStartDChan((int) m_strDeviceInfo.struDeviceV30.byStartDChan);
- //鑾峰彇鏈�鏂伴�氶亾
- List<ArdChannel> cameraChannelList = getCameraChannelList(camera);
- if (cameraChannelList.size() > 0) {
- for (ArdChannel channel : cameraChannelList) {
- channel.setId(IdUtils.simpleUUID());
- ardChannelService.insertArdChannel(channel);
+ // 娉ㄥ唽璁惧-鐧诲綍鍙傛暟锛屽寘鎷澶囧湴鍧�銆佺櫥褰曠敤鎴枫�佸瘑鐮佺瓑
+ m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+ System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
+ m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+ System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
+ m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
+ System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
+ m_strLoginInfo.wPort = m_sPort;
+ m_strLoginInfo.byVerifyMode = 0;
+ m_strLoginInfo.byLoginMode = 0;
+ //鏄惁寮傛鐧诲綍锛�0- 鍚︼紝1- 鏄� windowsSDK閲屾槸true鍜宖alse
+ m_strLoginInfo.bUseAsynLogin = false;
+ m_strLoginInfo.write();
+ //鍚屾鐧诲綍
+ int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
+ if (lUserID < 0) {
+ int errorCode = hCNetSDK.NET_DVR_GetLastError();
+ log.debug(camera.getIp() + ":" + camera.getPort() + "鐧诲綍澶辫触,閿欒鐮侊細" + errorCode);
+ camera.setChanNum(0);
+ camera.setLoginId(-1);
+ camera.setState("0");
+ } else {
+ if (fExceptionCallBack == null) {
+ fExceptionCallBack = new ExceptionCallBack();//寮傚父鍥炶皟
+ //璁剧疆寮傚父鍥炶皟鍑芥暟(鍙湪鍥炶皟鍑芥暟涓幏鍙栬澶囦笂涓嬬嚎鐘舵�佺瓑)
+ if (!hCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, 0, fExceptionCallBack, null)) {
+ log.info("Set fExceptionCallBack function fail");
+ return;
+ } else {
+ log.info("Set fExceptionCallBack function successfully!");
+ }
}
- //娣诲姞鍒版祦濯掍綋
- for (ArdChannel channel : cameraChannelList) {
- String name = camera.getId() + "_" + channel.getChanNo();
- String rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream";
- Vtdu vtdu = vtduService.selectVtduByName(name);
- if (vtdu != null) {
- vtduService.deleteVtduByName(name);
+
+ if (GlobalVariable.loginMap.containsKey(camera.getId())) {
+ GlobalVariable.loginMap.remove(camera.getId());
+ }
+ //鍒犻櫎绠$悊閫氶亾
+ ardChannelService.deleteArdChannelByDeviceId(camera.getId());
+ GlobalVariable.loginMap.put(camera.getId(), lUserID);
+ GlobalVariable.loginCameraMap.put(lUserID, camera);
+
+ log.debug("Login Success [ " + camera.getIp() + ":" + camera.getPort() + " ]");
+ camera.setLoginId(lUserID);
+ camera.setState("1");
+ camera.setChanNum((int) m_strDeviceInfo.struDeviceV30.byChanNum);
+ camera.setStartDChan((int) m_strDeviceInfo.struDeviceV30.byStartDChan);
+ //鑾峰彇鏈�鏂伴�氶亾
+ List<ArdChannel> cameraChannelList = getCameraChannelList(camera);
+ if (cameraChannelList.size() > 0) {
+ for (ArdChannel channel : cameraChannelList) {
+ channel.setId(IdUtils.simpleUUID());
+ ardChannelService.insertArdChannel(channel);
}
//娣诲姞鍒版祦濯掍綋
- vtdu = new Vtdu();
- vtdu.setRtspSource(rtspSource);
- vtdu.setName(camera.getId() + "_" + channel.getChanNo());
- CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo());
- Map<String, Object> videoCompressionCfg = getVideoCompressionCfg(cmd);
- if (videoCompressionCfg.get("videoEncType").equals("鏍囧噯h264")) {
- vtdu.setIsCode("0");//榛樿涓嶈浆鐮�
- } else {
- vtdu.setIsCode("1");//榛樿杞爜
+ for (ArdChannel channel : cameraChannelList) {
+ String name = camera.getId() + "_" + channel.getChanNo();
+ String rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream";
+ Vtdu vtdu = vtduService.selectVtduByName(name);
+ if (vtdu != null) {
+ vtduService.deleteVtduByName(name);
+ }
+ //娣诲姞鍒版祦濯掍綋
+ vtdu = new Vtdu();
+ vtdu.setRtspSource(rtspSource);
+ vtdu.setName(camera.getId() + "_" + channel.getChanNo());
+ CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo());
+ Map<String, Object> videoCompressionCfg = getVideoCompressionCfg(cmd);
+ if (videoCompressionCfg.get("videoEncType").equals("鏍囧噯h264")) {
+ vtdu.setIsCode("0");//榛樿涓嶈浆鐮�
+ } else {
+ vtdu.setIsCode("1");//榛樿杞爜
+ }
+ vtdu.setMode("1");//榛樿CPU杞В鐮�
+ vtdu.setCameraId(camera.getId());
+ vtduService.insertVtdu(vtdu);
}
- vtdu.setMode("1");//榛樿CPU杞В鐮�
- vtdu.setCameraId(camera.getId());
- vtduService.insertVtdu(vtdu);
}
+ //鍒涘缓寮曞闃熷垪
+ if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
+ Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
+ PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
+ GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
+ }
+ ardCamerasService.updateArdCameras(camera);
}
- //鍒涘缓寮曞闃熷垪
- if (!GuidePriorityQueue.cameraQueueMap.containsKey(camera.getId())) {
- Comparator<GuideTask> comparator = GuidePriorityQueue.getComparator();
- PriorityBlockingQueue<GuideTask> priorityQueue = new PriorityBlockingQueue<>(1000, comparator);
- GuidePriorityQueue.cameraQueueMap.put(camera.getId(), priorityQueue);
- }
- ardCamerasService.updateArdCameras(camera);
+ } catch (Exception ex) {
+ log.error("娉ㄥ唽璁惧寮傚父", ex);
}
}
diff --git a/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaServiceImpl.java b/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaServiceImpl.java
index c0326e2..946ea51 100644
--- a/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaServiceImpl.java
+++ b/ard-work/src/main/java/com/ruoyi/media/service/impl/MediaServiceImpl.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.dtflys.forest.exceptions.ForestNetworkException;
+import com.dtflys.forest.exceptions.ForestRuntimeException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.media.domain.*;
import com.ruoyi.media.service.IMediaService;
@@ -25,7 +26,7 @@
* @Version: 1.0
**/
@Service
-@Slf4j(topic = "cmd")
+@Slf4j(topic = "vtdu")
@Order(2)
public class MediaServiceImpl implements IMediaService {
@@ -47,37 +48,41 @@
*/
@Override
public Map<String, String> addPath(String name, String sourceUrl, String mode, String isCode) {
-
- String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name;
- String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name;
- String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name;
-
- Conf conf = new Conf();
- String rootPath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/lib/mediamtx/";
- if (isCode.equals("1")) {
- conf.setSource("publisher");
- //榛樿杞В鐮�
- String cmd = "ffmpeg -rtsp_transport tcp -i " + sourceUrl + " -vcodec libx264 -preset:v ultrafast -r 25 -keyint_min 25 -g 60 -sc_threshold 0 -threads 6 -b:v 2048k -acodec opus -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH";
- if (mode.equals("0")) {//纭В鐮�
- cmd = "ffmpeg -hwaccel cuvid -c:v hevc_cuvid -rtsp_transport tcp -i " + sourceUrl + " -c:v h264_nvenc -r 25 -g 60 -sc_threshold 0 -threads 6 -b:v 2048k -bf 0 -acodec opus -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH";
- }
- conf.setRunOnDemand(cmd);
- conf.setRunOnDemandRestart(true);
- conf.setRunOnDemandCloseAfter("5s");
- } else {
- conf.setSource(sourceUrl);
- conf.setSourceOnDemand(true);
- }
- conf.setMaxReaders(100);
- conf.setSourceProtocol("tcp");
-
- if (!checkNameExist(name)) {
- mediaClient.addPath(name, conf);
- }
Map<String, String> map = new HashMap<>();
- map.put("rtspUrl", rtspUrl);
- map.put("rtmpUrl", rtmpUrl);
- map.put("webrtcUrl", webrtcUrl);
+ try {
+ String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name;
+ String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name;
+ String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name;
+
+ Conf conf = new Conf();
+ String rootPath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/lib/mediamtx/";
+ if (isCode.equals("1")) {
+ conf.setSource("publisher");
+ //榛樿杞В鐮�
+ String cmd = "ffmpeg -rtsp_transport tcp -i " + sourceUrl + " -vcodec libx264 -preset:v ultrafast -r 25 -keyint_min 25 -g 60 -sc_threshold 0 -threads 6 -b:v 2048k -acodec opus -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH";
+ if (mode.equals("0")) {//纭В鐮�
+ cmd = "ffmpeg -hwaccel cuvid -c:v hevc_cuvid -rtsp_transport tcp -i " + sourceUrl + " -c:v h264_nvenc -r 25 -g 60 -sc_threshold 0 -threads 6 -b:v 2048k -bf 0 -acodec opus -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH";
+ }
+ conf.setRunOnDemand(cmd);
+ conf.setRunOnDemandRestart(true);
+ conf.setRunOnDemandCloseAfter("5s");
+ } else {
+ conf.setSource(sourceUrl);
+ conf.setSourceOnDemand(true);
+ }
+ conf.setMaxReaders(100);
+ conf.setSourceProtocol("tcp");
+
+ if (!checkNameExist(name)) {
+ mediaClient.addPath(name, conf);
+ }
+
+ map.put("rtspUrl", rtspUrl);
+ map.put("rtmpUrl", rtmpUrl);
+ map.put("webrtcUrl", webrtcUrl);
+ } catch (ForestRuntimeException ex) {
+ log.error("娣诲姞娴佸獟浣撳紓甯革細"+ex.getMessage());
+ }
return map;
}
@@ -118,8 +123,8 @@
map.put("rtspUrl", rtspUrl);
map.put("rtmpUrl", rtmpUrl);
map.put("webrtcUrl", webrtcUrl);
- } catch (ForestNetworkException ex) {
- log.error(ex.getMessage());
+ } catch (ForestRuntimeException ex) {
+ log.error("淇敼娴佸獟浣撳紓甯革細"+ex.getMessage());
}
return map;
}
@@ -158,8 +163,12 @@
@Override
public void removePath(String name) {
- if (checkNameExist(name)) {
- mediaClient.removePath(name);
+ try {
+ if (checkNameExist(name)) {
+ mediaClient.removePath(name);
+ }
+ } catch (ForestRuntimeException ex) {
+ log.error("绉婚櫎娴佸獟浣撳紓甯革細"+ex.getMessage());
}
}
@@ -447,11 +456,15 @@
@Override
public List<String> getNameList() {
List<String> nameList = new ArrayList<>();
- String paths = mediaClient.paths();
- JsonsRoot jsonsRoot = JSONObject.parseObject(paths, JsonsRoot.class);
- List<Items> items = jsonsRoot.getItems();
- for (Items item : items) {
- nameList.add(item.getName());
+ try {
+ String paths = mediaClient.paths();
+ JsonsRoot jsonsRoot = JSONObject.parseObject(paths, JsonsRoot.class);
+ List<Items> items = jsonsRoot.getItems();
+ for (Items item : items) {
+ nameList.add(item.getName());
+ }
+ } catch (ForestRuntimeException ex) {
+ log.error("鑾峰彇娴佸獟浣搉ame鍒楄〃寮傚父锛�"+ex.getMessage());
}
return nameList;
}
diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml
index e0fd797..08c2b1c 100644
--- a/ruoyi-admin/src/main/resources/logback.xml
+++ b/ruoyi-admin/src/main/resources/logback.xml
@@ -250,6 +250,19 @@
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
+ <!--娴佸獟浣撴棩蹇楄緭鍑�-->
+ <appender name="vtdu" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${log.path}/vtdu.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <!--鎸夊ぉ鍥炴粴daily-->
+ <fileNamePattern>${log.path}/vtdu.%d{yyyy-MM-dd}.log</fileNamePattern>
+ <!--鏃ュ織鏈�澶х殑鍘嗗彶60澶�-->
+ <maxHistory>60</maxHistory>
+ </rollingPolicy>
+ <encoder>
+ <pattern>${log.pattern}</pattern>
+ </encoder>
+ </appender>
<!-- 绯荤粺妯″潡鏃ュ織绾у埆鎺у埗 -->
<logger name="com.ruoyi" level="info"/>
<!-- Spring鏃ュ織绾у埆鎺у埗 -->
@@ -299,6 +312,10 @@
<logger name="sy" level="INFO">
<appender-ref ref="sy"/>
</logger>
+ <!--vtdu鏃ュ織-->
+ <logger name="vtdu" level="INFO">
+ <appender-ref ref="vtdu"/>
+ </logger>
<!--rongCloud鏃ュ織-->
<logger name="rongCloud" level="INFO">
<appender-ref ref="rongCloud"/>
diff --git a/server/mediamtx/LICENSE b/server/mediamtx/LICENSE
new file mode 100644
index 0000000..bfbf85a
--- /dev/null
+++ b/server/mediamtx/LICENSE
@@ -0,0 +1,26 @@
+MIT License
+
+Copyright (c) 2019 aler9
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+internal/core/hls.min.js is Copyright (c) Dailymotion and is protected by
+its own license (Apache License, Version 2.0) available at
+
+https://github.com/video-dev/hls.js/blob/master/LICENSE
diff --git a/server/mediamtx/ffmpeg.exe b/server/mediamtx/ffmpeg.exe
new file mode 100644
index 0000000..a562fa0
--- /dev/null
+++ b/server/mediamtx/ffmpeg.exe
Binary files differ
diff --git a/server/mediamtx/mediamtx.exe b/server/mediamtx/mediamtx.exe
new file mode 100644
index 0000000..6457d07
--- /dev/null
+++ b/server/mediamtx/mediamtx.exe
Binary files differ
diff --git a/server/mediamtx/mediamtx.yml b/server/mediamtx/mediamtx.yml
new file mode 100644
index 0000000..e9a8e83
--- /dev/null
+++ b/server/mediamtx/mediamtx.yml
@@ -0,0 +1,556 @@
+###############################################
+# Global settings
+
+# Settings in this section are applied anywhere.
+
+###############################################
+# Global settings -> General
+
+# Verbosity of the program; available values are "error", "warn", "info", "debug".
+logLevel: info
+# Destinations of log messages; available values are "stdout", "file" and "syslog".
+logDestinations: [stdout]
+# If "file" is in logDestinations, this is the file which will receive the logs.
+logFile: mediamtx.log
+
+# Timeout of read operations.
+readTimeout: 10s
+# Timeout of write operations.
+writeTimeout: 10s
+# Size of the queue of outgoing packets.
+# A higher value allows to increase throughput, a lower value allows to save RAM.
+writeQueueSize: 512
+# Maximum size of outgoing UDP packets.
+# This can be decreased to avoid fragmentation on networks with a low UDP MTU.
+udpMaxPayloadSize: 1472
+
+# HTTP URL to perform external authentication.
+# Every time a user wants to authenticate, the server calls this URL
+# with the POST method and a body containing:
+# {
+# "ip": "ip",
+# "user": "user",
+# "password": "password",
+# "path": "path",
+# "protocol": "rtsp|rtmp|hls|webrtc",
+# "id": "id",
+# "action": "read|publish",
+# "query": "query"
+# }
+# If the response code is 20x, authentication is accepted, otherwise
+# it is discarded.
+externalAuthenticationURL:
+
+# Enable the HTTP API.
+api: yes
+# Address of the API listener.
+apiAddress: 192.168.5.229:9997
+
+# Enable Prometheus-compatible metrics.
+metrics: no
+# Address of the metrics listener.
+metricsAddress: 127.0.0.1:9998
+
+# Enable pprof-compatible endpoint to monitor performances.
+pprof: no
+# Address of the pprof listener.
+pprofAddress: 127.0.0.1:9999
+
+# Command to run when a client connects to the server.
+# This is terminated with SIGINT when a client disconnects from the server.
+# The following environment variables are available:
+# * RTSP_PORT: RTSP server port
+# * MTX_CONN_TYPE: connection type
+# * MTX_CONN_ID: connection ID
+runOnConnect:
+# Restart the command if it exits.
+runOnConnectRestart: no
+# Command to run when a client disconnects from the server.
+# Environment variables are the same of runOnConnect.
+runOnDisconnect:
+
+###############################################
+# Global settings -> RTSP
+
+# Allow publishing and reading streams with the RTSP protocol.
+rtsp: yes
+# List of enabled RTSP transport protocols.
+# UDP is the most performant, but doesn't work when there's a NAT/firewall between
+# server and clients, and doesn't support encryption.
+# UDP-multicast allows to save bandwidth when clients are all in the same LAN.
+# TCP is the most versatile, and does support encryption.
+# The handshake is always performed with TCP.
+protocols: [udp, multicast, tcp]
+# Encrypt handshakes and TCP streams with TLS (RTSPS).
+# Available values are "no", "strict", "optional".
+encryption: "no"
+# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
+rtspAddress: :8554
+# Address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional".
+rtspsAddress: :8322
+# Address of the UDP/RTP listener. This is needed only when "udp" is in protocols.
+rtpAddress: :8000
+# Address of the UDP/RTCP listener. This is needed only when "udp" is in protocols.
+rtcpAddress: :8001
+# IP range of all UDP-multicast listeners. This is needed only when "multicast" is in protocols.
+multicastIPRange: 224.1.0.0/16
+# Port of all UDP-multicast/RTP listeners. This is needed only when "multicast" is in protocols.
+multicastRTPPort: 8002
+# Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in protocols.
+multicastRTCPPort: 8003
+# Path to the server key. This is needed only when encryption is "strict" or "optional".
+# This can be generated with:
+# openssl genrsa -out server.key 2048
+# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
+serverKey: server.key
+# Path to the server certificate. This is needed only when encryption is "strict" or "optional".
+serverCert: server.crt
+# Authentication methods. Available are "basic" and "digest".
+# "digest" doesn't provide any additional security and is available for compatibility reasons only.
+authMethods: [basic]
+
+###############################################
+# Global settings -> RTMP
+
+# Allow publishing and reading streams with the RTMP protocol.
+rtmp: yes
+# Address of the RTMP listener. This is needed only when encryption is "no" or "optional".
+rtmpAddress: :1935
+# Encrypt connections with TLS (RTMPS).
+# Available values are "no", "strict", "optional".
+rtmpEncryption: "no"
+# Address of the RTMPS listener. This is needed only when encryption is "strict" or "optional".
+rtmpsAddress: :1936
+# Path to the server key. This is needed only when encryption is "strict" or "optional".
+# This can be generated with:
+# openssl genrsa -out server.key 2048
+# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
+rtmpServerKey: server.key
+# Path to the server certificate. This is needed only when encryption is "strict" or "optional".
+rtmpServerCert: server.crt
+
+###############################################
+# Global settings -> HLS
+
+# Allow reading streams with the HLS protocol.
+hls: no
+# Address of the HLS listener.
+hlsAddress: :8888
+# Enable TLS/HTTPS on the HLS server.
+# This is required for Low-Latency HLS.
+hlsEncryption: no
+# Path to the server key. This is needed only when encryption is yes.
+# This can be generated with:
+# openssl genrsa -out server.key 2048
+# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
+hlsServerKey: server.key
+# Path to the server certificate.
+hlsServerCert: server.crt
+# By default, HLS is generated only when requested by a user.
+# This option allows to generate it always, avoiding the delay between request and generation.
+hlsAlwaysRemux: no
+# Variant of the HLS protocol to use. Available options are:
+# * mpegts - uses MPEG-TS segments, for maximum compatibility.
+# * fmp4 - uses fragmented MP4 segments, more efficient.
+# * lowLatency - uses Low-Latency HLS.
+hlsVariant: lowLatency
+# Number of HLS segments to keep on the server.
+# Segments allow to seek through the stream.
+# Their number doesn't influence latency.
+hlsSegmentCount: 7
+# Minimum duration of each segment.
+# A player usually puts 3 segments in a buffer before reproducing the stream.
+# The final segment duration is also influenced by the interval between IDR frames,
+# since the server changes the duration in order to include at least one IDR frame
+# in each segment.
+hlsSegmentDuration: 1s
+# Minimum duration of each part.
+# A player usually puts 3 parts in a buffer before reproducing the stream.
+# Parts are used in Low-Latency HLS in place of segments.
+# Part duration is influenced by the distance between video/audio samples
+# and is adjusted in order to produce segments with a similar duration.
+hlsPartDuration: 200ms
+# Maximum size of each segment.
+# This prevents RAM exhaustion.
+hlsSegmentMaxSize: 50M
+# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
+# This allows to play the HLS stream from an external website.
+hlsAllowOrigin: '*'
+# List of IPs or CIDRs of proxies placed before the HLS server.
+# If the server receives a request from one of these entries, IP in logs
+# will be taken from the X-Forwarded-For header.
+hlsTrustedProxies: []
+# Directory in which to save segments, instead of keeping them in the RAM.
+# This decreases performance, since reading from disk is less performant than
+# reading from RAM, but allows to save RAM.
+hlsDirectory: ''
+
+###############################################
+# Global settings -> WebRTC
+
+# Allow publishing and reading streams with the WebRTC protocol.
+webrtc: yes
+# Address of the WebRTC listener.
+webrtcAddress: :8889
+# Enable TLS/HTTPS on the WebRTC server.
+webrtcEncryption: no
+# Path to the server key.
+# This can be generated with:
+# openssl genrsa -out server.key 2048
+# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
+webrtcServerKey: server.key
+# Path to the server certificate.
+webrtcServerCert: server.crt
+# Value of the Access-Control-Allow-Origin header provided in every HTTP response.
+# This allows to play the WebRTC stream from an external website.
+webrtcAllowOrigin: '*'
+# List of IPs or CIDRs of proxies placed before the WebRTC server.
+# If the server receives a request from one of these entries, IP in logs
+# will be taken from the X-Forwarded-For header.
+webrtcTrustedProxies: []
+# List of ICE servers.
+webrtcICEServers2:
+ # URL can point to a STUN, TURN or TURNS server.
+ # STUN servers are used to obtain the public IP of server and clients. They are
+ # needed when server and clients are on different LANs.
+ # TURN/TURNS servers are needed when a direct connection between server and
+ # clients is not possible. All traffic is routed through them.
+- url: stun:112.98.126.2:3478
+ # if user is "AUTH_SECRET", then authentication is secret based.
+ # the secret must be inserted into the password field.
+ username: 'admin'
+ password: '123456'
+# List of interfaces that will be used to gather IPs to send
+# to the counterpart to establish a connection.
+webrtcICEInterfaces: []
+# List of public IP addresses that are to be used as a host.
+# This is used typically for servers that are behind 1:1 D-NAT.
+webrtcICEHostNAT1To1IPs: [112.98.126.2]
+# Address of a ICE UDP listener in format host:port.
+# If filled, ICE traffic will pass through a single UDP port,
+# allowing the deployment of the server inside a container or behind a NAT.
+webrtcICEUDPMuxAddress: 192.168.5.229:1234
+# Address of a ICE TCP listener in format host:port.
+# If filled, ICE traffic will pass through a single TCP port,
+# allowing the deployment of the server inside a container or behind a NAT.
+# Using this setting forces usage of the TCP protocol, which is not
+# optimal for WebRTC.
+webrtcICETCPMuxAddress: 192.168.5.229:1234
+
+###############################################
+# Global settings -> SRT
+
+# Allow publishing and reading streams with the SRT protocol.
+srt: no
+# Address of the SRT listener.
+srtAddress: :8890
+
+###############################################
+# Default path settings
+
+# Settings in "pathDefaults" are applied anywhere,
+# unless they are overridden in "paths".
+pathDefaults:
+
+ ###############################################
+ # Default path settings -> General
+
+ # Source of the stream. This can be:
+ # * publisher -> the stream is provided by a RTSP, RTMP, WebRTC or SRT client
+ # * rtsp://existing-url -> the stream is pulled from another RTSP server / camera
+ # * rtsps://existing-url -> the stream is pulled from another RTSP server / camera with RTSPS
+ # * rtmp://existing-url -> the stream is pulled from another RTMP server / camera
+ # * rtmps://existing-url -> the stream is pulled from another RTMP server / camera with RTMPS
+ # * http://existing-url/stream.m3u8 -> the stream is pulled from another HLS server / camera
+ # * https://existing-url/stream.m3u8 -> the stream is pulled from another HLS server / camera with HTTPS
+ # * udp://ip:port -> the stream is pulled with UDP, by listening on the specified IP and port
+ # * srt://existing-url -> the stream is pulled from another SRT server / camera
+ # * whep://existing-url -> the stream is pulled from another WebRTC server / camera
+ # * wheps://existing-url -> the stream is pulled from another WebRTC server / camera with HTTPS
+ # * redirect -> the stream is provided by another path or server
+ # * rpiCamera -> the stream is provided by a Raspberry Pi Camera
+ source: publisher
+ # If the source is a URL, and the source certificate is self-signed
+ # or invalid, you can provide the fingerprint of the certificate in order to
+ # validate it anyway. It can be obtained by running:
+ # openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
+ # openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
+ sourceFingerprint:
+ # If the source is a URL, it will be pulled only when at least
+ # one reader is connected, saving bandwidth.
+ sourceOnDemand: no
+ # If sourceOnDemand is "yes", readers will be put on hold until the source is
+ # ready or until this amount of time has passed.
+ sourceOnDemandStartTimeout: 10s
+ # If sourceOnDemand is "yes", the source will be closed when there are no
+ # readers connected and this amount of time has passed.
+ sourceOnDemandCloseAfter: 10s
+ # Maximum number of readers. Zero means no limit.
+ maxReaders: 0
+ # SRT encryption passphrase require to read from this path
+ srtReadPassphrase:
+
+ ###############################################
+ # Default path settings -> Recording
+
+ # Record streams to disk.
+ record: no
+ # Path of recording segments.
+ # Extension is added automatically.
+ # Available variables are %path (path name), %Y %m %d %H %M %S %f (time in strftime format)
+ recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S-%f
+ # Format of recorded segments.
+ # Available formats are "fmp4" (fragmented MP4) and "mpegts" (MPEG-TS).
+ recordFormat: fmp4
+ # fMP4 segments are concatenation of small MP4 files (parts), each with this duration.
+ # MPEG-TS segments are concatenation of 188-bytes packets, flushed to disk with this period.
+ # When a system failure occurs, the last part gets lost.
+ # Therefore, the part duration is equal to the RPO (recovery point objective).
+ recordPartDuration: 100ms
+ # Minimum duration of each segment.
+ recordSegmentDuration: 1h
+ # Delete segments after this timespan.
+ # Set to 0s to disable automatic deletion.
+ recordDeleteAfter: 24h
+
+ ###############################################
+ # Default path settings -> Authentication
+
+ # Username required to publish.
+ # SHA256-hashed values can be inserted with the "sha256:" prefix.
+ publishUser:
+ # Password required to publish.
+ # SHA256-hashed values can be inserted with the "sha256:" prefix.
+ publishPass:
+ # IPs or networks (x.x.x.x/24) allowed to publish.
+ publishIPs: []
+
+ # Username required to read.
+ # SHA256-hashed values can be inserted with the "sha256:" prefix.
+ readUser:
+ # password required to read.
+ # SHA256-hashed values can be inserted with the "sha256:" prefix.
+ readPass:
+ # IPs or networks (x.x.x.x/24) allowed to read.
+ readIPs: []
+
+ ###############################################
+ # Default path settings -> Publisher source (when source is "publisher")
+
+ # allow another client to disconnect the current publisher and publish in its place.
+ overridePublisher: yes
+ # if no one is publishing, redirect readers to this path.
+ # It can be can be a relative path (i.e. /otherstream) or an absolute RTSP URL.
+ fallback:
+ # SRT encryption passphrase required to publish to this path
+ srtPublishPassphrase:
+
+ ###############################################
+ # Default path settings -> RTSP source (when source is a RTSP or a RTSPS URL)
+
+ # protocol used to pull the stream. available values are "automatic", "udp", "multicast", "tcp".
+ sourceProtocol: automatic
+ # support sources that don't provide server ports or use random server ports. This is a security issue
+ # and must be used only when interacting with sources that require it.
+ sourceAnyPortEnable: no
+ # range header to send to the source, in order to start streaming from the specified offset.
+ # available values:
+ # * clock: Absolute time
+ # * npt: Normal Play Time
+ # * smpte: SMPTE timestamps relative to the start of the recording
+ rtspRangeType:
+ # available values:
+ # * clock: UTC ISO 8601 combined date and time string, e.g. 20230812T120000Z
+ # * npt: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "碌s"), "ms", "s", "m", "h"
+ # * smpte: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "碌s"), "ms", "s", "m", "h"
+ rtspRangeStart:
+
+ ###############################################
+ # Default path settings -> Redirect source (when source is "redirect")
+
+ # RTSP URL which clients will be redirected to.
+ sourceRedirect:
+
+ ###############################################
+ # Default path settings -> Raspberry Pi Camera source (when source is "rpiCamera")
+
+ # ID of the camera
+ rpiCameraCamID: 0
+ # width of frames
+ rpiCameraWidth: 1920
+ # height of frames
+ rpiCameraHeight: 1080
+ # flip horizontally
+ rpiCameraHFlip: false
+ # flip vertically
+ rpiCameraVFlip: false
+ # brightness [-1, 1]
+ rpiCameraBrightness: 0
+ # contrast [0, 16]
+ rpiCameraContrast: 1
+ # saturation [0, 16]
+ rpiCameraSaturation: 1
+ # sharpness [0, 16]
+ rpiCameraSharpness: 1
+ # exposure mode.
+ # values: normal, short, long, custom
+ rpiCameraExposure: normal
+ # auto-white-balance mode.
+ # values: auto, incandescent, tungsten, fluorescent, indoor, daylight, cloudy, custom
+ rpiCameraAWB: auto
+ # denoise operating mode.
+ # values: off, cdn_off, cdn_fast, cdn_hq
+ rpiCameraDenoise: "off"
+ # fixed shutter speed, in microseconds.
+ rpiCameraShutter: 0
+ # metering mode of the AEC/AGC algorithm.
+ # values: centre, spot, matrix, custom
+ rpiCameraMetering: centre
+ # fixed gain
+ rpiCameraGain: 0
+ # EV compensation of the image [-10, 10]
+ rpiCameraEV: 0
+ # Region of interest, in format x,y,width,height
+ rpiCameraROI:
+ # whether to enable HDR on Raspberry Camera 3.
+ rpiCameraHDR: false
+ # tuning file
+ rpiCameraTuningFile:
+ # sensor mode, in format [width]:[height]:[bit-depth]:[packing]
+ # bit-depth and packing are optional.
+ rpiCameraMode:
+ # frames per second
+ rpiCameraFPS: 30
+ # period between IDR frames
+ rpiCameraIDRPeriod: 60
+ # bitrate
+ rpiCameraBitrate: 1000000
+ # H264 profile
+ rpiCameraProfile: main
+ # H264 level
+ rpiCameraLevel: '4.1'
+ # Autofocus mode
+ # values: auto, manual, continuous
+ rpiCameraAfMode: auto
+ # Autofocus range
+ # values: normal, macro, full
+ rpiCameraAfRange: normal
+ # Autofocus speed
+ # values: normal, fast
+ rpiCameraAfSpeed: normal
+ # Lens position (for manual autofocus only), will be set to focus to a specific distance
+ # calculated by the following formula: d = 1 / value
+ # Examples: 0 moves the lens to infinity.
+ # 0.5 moves the lens to focus on objects 2m away.
+ # 2 moves the lens to focus on objects 50cm away.
+ rpiCameraLensPosition: 0.0
+ # Specifies the autofocus window, in the form x,y,width,height where the coordinates
+ # are given as a proportion of the entire image.
+ rpiCameraAfWindow:
+ # enables printing text on each frame.
+ rpiCameraTextOverlayEnable: false
+ # text that is printed on each frame.
+ # format is the one of the strftime() function.
+ rpiCameraTextOverlay: '%Y-%m-%d %H:%M:%S - MediaMTX'
+
+ ###############################################
+ # Default path settings -> Hooks
+
+ # Command to run when this path is initialized.
+ # This can be used to publish a stream when the server is launched.
+ # This is terminated with SIGINT when the program closes.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ runOnInit:
+ # Restart the command if it exits.
+ runOnInitRestart: no
+
+ # Command to run when this path is requested by a reader.
+ # This can be used to publish a stream on demand.
+ # This is terminated with SIGINT when the path is not requested anymore.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ runOnDemand:
+ # Restart the command if it exits.
+ runOnDemandRestart: no
+ # Readers will be put on hold until the runOnDemand command starts publishing
+ # or until this amount of time has passed.
+ runOnDemandStartTimeout: 10s
+ # The command will be closed when there are no
+ # readers connected and this amount of time has passed.
+ runOnDemandCloseAfter: 10s
+
+ # Command to run when the stream is ready to be read, whenever it is
+ # published by a client or pulled from a server / camera.
+ # This is terminated with SIGINT when the stream is not ready anymore.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ # * MTX_SOURCE_TYPE: source type
+ # * MTX_SOURCE_ID: source ID
+ runOnReady:
+ # Restart the command if it exits.
+ runOnReadyRestart: no
+ # Command to run when the stream is not available anymore.
+ # Environment variables are the same of runOnReady.
+ runOnNotReady:
+
+ # Command to run when a client starts reading.
+ # This is terminated with SIGINT when a client stops reading.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ # * MTX_READER_TYPE: reader type
+ # * MTX_READER_ID: reader ID
+ runOnRead:
+ # Restart the command if it exits.
+ runOnReadRestart: no
+ # Command to run when a client stops reading.
+ # Environment variables are the same of runOnRead.
+ runOnUnread:
+
+ # Command to run when a recording segment is created.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ # * MTX_SEGMENT_PATH: segment file path
+ runOnRecordSegmentCreate:
+
+ # Command to run when a recording segment is complete.
+ # The following environment variables are available:
+ # * MTX_PATH: path name
+ # * RTSP_PORT: RTSP server port
+ # * G1, G2, ...: regular expression groups, if path name is
+ # a regular expression.
+ # * MTX_SEGMENT_PATH: segment file path
+ runOnRecordSegmentComplete:
+
+###############################################
+# Path settings
+
+# Settings in "paths" are applied to specific paths, and the map key
+# is the name of the path.
+# Any setting in "pathDefaults" can be overridden here.
+# It's possible to use regular expressions by using a tilde as prefix,
+# for example "~^(test1|test2)$" will match both "test1" and "test2",
+# for example "~^prefix" will match all paths that start with "prefix".
+paths:
+ # example:
+ # my_camera:
+ # source: rtsp://my_camera
+
+ # Settings under path "all_others" are applied to all paths that
+ # do not match another entry.
+ all_others:
diff --git a/server/redis/EventLog.dll b/server/redis/EventLog.dll
new file mode 100644
index 0000000..275c82f
--- /dev/null
+++ b/server/redis/EventLog.dll
Binary files differ
diff --git a/server/redis/Redis on Windows Release Notes.docx b/server/redis/Redis on Windows Release Notes.docx
new file mode 100644
index 0000000..a4490d0
--- /dev/null
+++ b/server/redis/Redis on Windows Release Notes.docx
Binary files differ
diff --git a/server/redis/Redis on Windows.docx b/server/redis/Redis on Windows.docx
new file mode 100644
index 0000000..6b7537f
--- /dev/null
+++ b/server/redis/Redis on Windows.docx
Binary files differ
diff --git a/server/redis/Windows Service Documentation.docx b/server/redis/Windows Service Documentation.docx
new file mode 100644
index 0000000..5e051ac
--- /dev/null
+++ b/server/redis/Windows Service Documentation.docx
Binary files differ
diff --git a/server/redis/dump.rdb b/server/redis/dump.rdb
new file mode 100644
index 0000000..1902907
--- /dev/null
+++ b/server/redis/dump.rdb
Binary files differ
diff --git a/server/redis/redis-benchmark.exe b/server/redis/redis-benchmark.exe
new file mode 100644
index 0000000..5dc07ff
--- /dev/null
+++ b/server/redis/redis-benchmark.exe
Binary files differ
diff --git a/server/redis/redis-benchmark.pdb b/server/redis/redis-benchmark.pdb
new file mode 100644
index 0000000..9ed1ebf
--- /dev/null
+++ b/server/redis/redis-benchmark.pdb
Binary files differ
diff --git a/server/redis/redis-check-aof.exe b/server/redis/redis-check-aof.exe
new file mode 100644
index 0000000..8a08279
--- /dev/null
+++ b/server/redis/redis-check-aof.exe
Binary files differ
diff --git a/server/redis/redis-check-aof.pdb b/server/redis/redis-check-aof.pdb
new file mode 100644
index 0000000..5534e6c
--- /dev/null
+++ b/server/redis/redis-check-aof.pdb
Binary files differ
diff --git a/server/redis/redis-cli.exe b/server/redis/redis-cli.exe
new file mode 100644
index 0000000..2f3aee6
--- /dev/null
+++ b/server/redis/redis-cli.exe
Binary files differ
diff --git a/server/redis/redis-cli.pdb b/server/redis/redis-cli.pdb
new file mode 100644
index 0000000..36af68c
--- /dev/null
+++ b/server/redis/redis-cli.pdb
Binary files differ
diff --git a/server/redis/redis-desktop-manager-0.9.3.817.exe b/server/redis/redis-desktop-manager-0.9.3.817.exe
new file mode 100644
index 0000000..f0d2db7
--- /dev/null
+++ b/server/redis/redis-desktop-manager-0.9.3.817.exe
Binary files differ
diff --git a/server/redis/redis-server.exe b/server/redis/redis-server.exe
new file mode 100644
index 0000000..5a60dca
--- /dev/null
+++ b/server/redis/redis-server.exe
Binary files differ
diff --git a/server/redis/redis-server.pdb b/server/redis/redis-server.pdb
new file mode 100644
index 0000000..da92744
--- /dev/null
+++ b/server/redis/redis-server.pdb
Binary files differ
diff --git a/server/redis/redis.windows-service.conf b/server/redis/redis.windows-service.conf
new file mode 100644
index 0000000..a344483
--- /dev/null
+++ b/server/redis/redis.windows-service.conf
@@ -0,0 +1,1048 @@
+# Redis configuration file example
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here. This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings. Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include .\path\to\local.conf
+# include c:\path\to\other.conf
+
+################################## NETWORK #####################################
+
+# By default, if no "bind" configuration directive is specified, Redis listens
+# for connections from all the network interfaces available on the server.
+# It is possible to listen to just one or multiple selected interfaces using
+# the "bind" configuration directive, followed by one or more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+# bind 127.0.0.1 ::1
+#
+# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
+# internet, binding to all the interfaces is dangerous and will expose the
+# instance to everybody on the internet. So by default we uncomment the
+# following bind directive, that will force Redis to listen only into
+# the IPv4 lookback interface address (this means Redis will be able to
+# accept connections only from clients running into the same computer it
+# is running).
+#
+# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
+# JUST COMMENT THE FOLLOWING LINE.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bind 127.0.0.1
+
+# Protected mode is a layer of security protection, in order to avoid that
+# Redis instances left open on the internet are accessed and exploited.
+#
+# When protected mode is on and if:
+#
+# 1) The server is not binding explicitly to a set of addresses using the
+# "bind" directive.
+# 2) No password is configured.
+#
+# The server only accepts connections from clients connecting from the
+# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
+# sockets.
+#
+# By default protected mode is enabled. You should disable it only if
+# you are sure you want clients from other hosts to connect to Redis
+# even if no authentication is configured, nor a specific set of interfaces
+# are explicitly listed using the "bind" directive.
+protected-mode yes
+
+# Accept connections on the specified port, default is 6379 (IANA #815344).
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6379
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# Unix socket.
+#
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+# equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+################################# GENERAL #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+# NOT SUPPORTED ON WINDOWS daemonize no
+
+# If you run Redis from upstart or systemd, Redis can interact with your
+# supervision tree. Options:
+# supervised no - no supervision interaction
+# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
+# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
+# supervised auto - detect upstart or systemd method based on
+# UPSTART_JOB or NOTIFY_SOCKET environment variables
+# Note: these supervision methods only signal "process is ready."
+# They do not enable continuous liveness pings back to your supervisor.
+# NOT SUPPORTED ON WINDOWS supervised no
+
+# If a pid file is specified, Redis writes it where specified at startup
+# and removes it at exit.
+#
+# When the server runs non daemonized, no pid file is created if none is
+# specified in the configuration. When the server is daemonized, the pid file
+# is used even if not specified, defaulting to "/var/run/redis.pid".
+#
+# Creating a pid file is best effort: if Redis is not able to create it
+# nothing bad happens, the server will start and run normally.
+# NOT SUPPORTED ON WINDOWS pidfile /var/run/redis.pid
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also 'stdout' can be used to force
+# Redis to log on the standard output.
+logfile "server_log.txt"
+
+# To enable logging to the Windows EventLog, just set 'syslog-enabled' to
+# yes, and optionally update the other syslog parameters to suit your needs.
+# If Redis is installed and launched as a Windows Service, this will
+# automatically be enabled.
+syslog-enabled yes
+
+# Specify the source name of the events in the Windows Application log.
+syslog-ident redis
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING ################################
+#
+# Save the DB on disk:
+#
+# save <seconds> <changes>
+#
+# Will save the DB if both the given number of seconds and the given
+# number of write operations against the DB occurred.
+#
+# In the example below the behaviour will be to save:
+# after 900 sec (15 min) if at least 1 key changed
+# after 300 sec (5 min) if at least 10 keys changed
+# after 60 sec if at least 10000 keys changed
+#
+# Note: you can disable saving completely by commenting out all "save" lines.
+#
+# It is also possible to remove all the previously configured save
+# points by adding a save directive with a single empty string argument
+# like in the following example:
+#
+# save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error yes
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir ./
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+# stop accepting writes if it appears to be not connected with at least
+# a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+# master if the replication link is lost for a relatively small amount of
+# time. You may want to configure the replication backlog size (see the next
+# sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+# network partition slaves automatically try to reconnect to masters
+# and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+# still reply to client requests, possibly with out of date data, or the
+# data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+# an error "SYNC with master in progress" to all the kind of commands
+# but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+# file on disk. Later the file is transferred by the parent
+# process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+# RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands. This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# If Redis is to be used as an in-memory-only cache without any kind of
+# persistence, then the fork() mechanism used by the background AOF/RDB
+# persistence is unnecessary. As an optimization, all persistence can be
+# turned off in the Windows version of Redis. This will redirect heap
+# allocations to the system heap allocator, and disable commands that would
+# otherwise cause fork() operations: BGSAVE and BGREWRITEAOF.
+# This flag may not be combined with any of the other flags that configure
+# AOF and RDB operations.
+# persistence-available [(yes)|no]
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# WARNING: not setting maxmemory will cause Redis to terminate with an
+# out-of-memory exception if the heap limit is reached.
+#
+# NOTE: since Redis uses the system paging file to allocate the heap memory,
+# the Working Set memory usage showed by the Windows Task Manager or by other
+# tools such as ProcessExplorer will not always be accurate. For example, right
+# after a background save of the RDB or the AOF files, the working set value
+# may drop significantly. In order to check the correct amount of memory used
+# by the redis-server to store the data, use the INFO client command. The INFO
+# command shows only the memory used to store the redis data, not the extra
+# memory used by the Windows process for its own requirements. Th3 extra amount
+# of memory not reported by the INFO command can be calculated subtracting the
+# Peak Working Set reported by the Windows Task Manager and the used_memory_peak
+# reported by the INFO command.
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+# operations, when there are no suitable keys for eviction.
+#
+# At the date of writing these commands are: set setnx setex append
+# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+# getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+# in order to try to give an advantage to the slave with the best
+# replication offset (more data from the master processed).
+# Slaves will try to get their rank by offset, and apply to the start
+# of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+# its master. This can be the last ping or command received (if the master
+# is still in the "connected" state), or the time that elapsed since the
+# disconnection with the master (if the replication link is currently down).
+# If the last interaction is too old, the slave will not try to failover
+# at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+# (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+# K Keyspace events, published with __keyspace@<db>__ prefix.
+# E Keyevent events, published with __keyevent@<db>__ prefix.
+# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+# $ String commands
+# l List commands
+# s Set commands
+# h Hash commands
+# z Sorted set commands
+# x Expired events (events generated every time a key expires)
+# e Evicted events (events generated when a key is evicted for maxmemory)
+# A Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+# The "notify-keyspace-events" takes as argument a string that is composed
+# of zero or multiple characters. The empty string means that notifications
+# are disabled.
+#
+# Example: to enable list and generic events, from the point of view of the
+# event name, use:
+#
+# notify-keyspace-events Elg
+#
+# Example 2: to get the stream of the expired keys subscribing to channel
+# name __keyevent@0__:expired use:
+#
+# notify-keyspace-events Ex
+#
+# By default all notifications are disabled because most users don't need
+# this feature and the feature has some overhead. Note that if you don't
+# specify at least one of K or E, no events will be delivered.
+notify-keyspace-events ""
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Lists are also encoded in a special way to save a lot of space.
+# The number of entries allowed per internal list node can be specified
+# as a fixed maximum size or a maximum number of elements.
+# For a fixed maximum size, use -5 through -1, meaning:
+# -5: max size: 64 Kb <-- not recommended for normal workloads
+# -4: max size: 32 Kb <-- not recommended
+# -3: max size: 16 Kb <-- probably not recommended
+# -2: max size: 8 Kb <-- good
+# -1: max size: 4 Kb <-- good
+# Positive numbers mean store up to _exactly_ that number of elements
+# per list node.
+# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
+# but if your use case is unique, adjust the settings as necessary.
+list-max-ziplist-size -2
+
+# Lists may also be compressed.
+# Compress depth is the number of quicklist ziplist nodes from *each* side of
+# the list to *exclude* from compression. The head and tail of the list
+# are always uncompressed for fast push/pop operations. Settings are:
+# 0: disable all list compression
+# 1: depth 1 means "don't start compressing until after 1 node into the list,
+# going from either the head or tail"
+# So: [head]->node->node->...->node->[tail]
+# [head], [tail] will always be uncompressed; inner nodes will compress.
+# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
+# 2 here means: don't compress head or head->next or tail->prev or tail,
+# but compress all nodes between them.
+# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
+# etc.
+list-compress-depth 0
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeot, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are perforemd with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here. This is useful if you
+# have a standard template that goes to all Redis server but also need
+# to customize a few per-server settings. Include files can include
+# other files, so use this wisely.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
diff --git a/server/redis/redis.windows.conf b/server/redis/redis.windows.conf
new file mode 100644
index 0000000..1564c30
--- /dev/null
+++ b/server/redis/redis.windows.conf
@@ -0,0 +1,1048 @@
+# Redis configuration file example
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here. This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings. Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include .\path\to\local.conf
+# include c:\path\to\other.conf
+
+################################## NETWORK #####################################
+
+# By default, if no "bind" configuration directive is specified, Redis listens
+# for connections from all the network interfaces available on the server.
+# It is possible to listen to just one or multiple selected interfaces using
+# the "bind" configuration directive, followed by one or more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+# bind 127.0.0.1 ::1
+#
+# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
+# internet, binding to all the interfaces is dangerous and will expose the
+# instance to everybody on the internet. So by default we uncomment the
+# following bind directive, that will force Redis to listen only into
+# the IPv4 lookback interface address (this means Redis will be able to
+# accept connections only from clients running into the same computer it
+# is running).
+#
+# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
+# JUST COMMENT THE FOLLOWING LINE.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bind 127.0.0.1
+
+# Protected mode is a layer of security protection, in order to avoid that
+# Redis instances left open on the internet are accessed and exploited.
+#
+# When protected mode is on and if:
+#
+# 1) The server is not binding explicitly to a set of addresses using the
+# "bind" directive.
+# 2) No password is configured.
+#
+# The server only accepts connections from clients connecting from the
+# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
+# sockets.
+#
+# By default protected mode is enabled. You should disable it only if
+# you are sure you want clients from other hosts to connect to Redis
+# even if no authentication is configured, nor a specific set of interfaces
+# are explicitly listed using the "bind" directive.
+protected-mode yes
+
+# Accept connections on the specified port, default is 6379 (IANA #815344).
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6379
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# Unix socket.
+#
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+# equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+################################# GENERAL #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+# NOT SUPPORTED ON WINDOWS daemonize no
+
+# If you run Redis from upstart or systemd, Redis can interact with your
+# supervision tree. Options:
+# supervised no - no supervision interaction
+# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
+# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
+# supervised auto - detect upstart or systemd method based on
+# UPSTART_JOB or NOTIFY_SOCKET environment variables
+# Note: these supervision methods only signal "process is ready."
+# They do not enable continuous liveness pings back to your supervisor.
+# NOT SUPPORTED ON WINDOWS supervised no
+
+# If a pid file is specified, Redis writes it where specified at startup
+# and removes it at exit.
+#
+# When the server runs non daemonized, no pid file is created if none is
+# specified in the configuration. When the server is daemonized, the pid file
+# is used even if not specified, defaulting to "/var/run/redis.pid".
+#
+# Creating a pid file is best effort: if Redis is not able to create it
+# nothing bad happens, the server will start and run normally.
+# NOT SUPPORTED ON WINDOWS pidfile /var/run/redis.pid
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also 'stdout' can be used to force
+# Redis to log on the standard output.
+logfile ""
+
+# To enable logging to the Windows EventLog, just set 'syslog-enabled' to
+# yes, and optionally update the other syslog parameters to suit your needs.
+# If Redis is installed and launched as a Windows Service, this will
+# automatically be enabled.
+# syslog-enabled no
+
+# Specify the source name of the events in the Windows Application log.
+# syslog-ident redis
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING ################################
+#
+# Save the DB on disk:
+#
+# save <seconds> <changes>
+#
+# Will save the DB if both the given number of seconds and the given
+# number of write operations against the DB occurred.
+#
+# In the example below the behaviour will be to save:
+# after 900 sec (15 min) if at least 1 key changed
+# after 300 sec (5 min) if at least 10 keys changed
+# after 60 sec if at least 10000 keys changed
+#
+# Note: you can disable saving completely by commenting out all "save" lines.
+#
+# It is also possible to remove all the previously configured save
+# points by adding a save directive with a single empty string argument
+# like in the following example:
+#
+# save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error yes
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir ./
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+# stop accepting writes if it appears to be not connected with at least
+# a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+# master if the replication link is lost for a relatively small amount of
+# time. You may want to configure the replication backlog size (see the next
+# sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+# network partition slaves automatically try to reconnect to masters
+# and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+# still reply to client requests, possibly with out of date data, or the
+# data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+# an error "SYNC with master in progress" to all the kind of commands
+# but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+# file on disk. Later the file is transferred by the parent
+# process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+# RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands. This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+# requirepass 浣犵殑瀵嗙爜
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# If Redis is to be used as an in-memory-only cache without any kind of
+# persistence, then the fork() mechanism used by the background AOF/RDB
+# persistence is unnecessary. As an optimization, all persistence can be
+# turned off in the Windows version of Redis. This will redirect heap
+# allocations to the system heap allocator, and disable commands that would
+# otherwise cause fork() operations: BGSAVE and BGREWRITEAOF.
+# This flag may not be combined with any of the other flags that configure
+# AOF and RDB operations.
+# persistence-available [(yes)|no]
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# WARNING: not setting maxmemory will cause Redis to terminate with an
+# out-of-memory exception if the heap limit is reached.
+#
+# NOTE: since Redis uses the system paging file to allocate the heap memory,
+# the Working Set memory usage showed by the Windows Task Manager or by other
+# tools such as ProcessExplorer will not always be accurate. For example, right
+# after a background save of the RDB or the AOF files, the working set value
+# may drop significantly. In order to check the correct amount of memory used
+# by the redis-server to store the data, use the INFO client command. The INFO
+# command shows only the memory used to store the redis data, not the extra
+# memory used by the Windows process for its own requirements. Th3 extra amount
+# of memory not reported by the INFO command can be calculated subtracting the
+# Peak Working Set reported by the Windows Task Manager and the used_memory_peak
+# reported by the INFO command.
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+# operations, when there are no suitable keys for eviction.
+#
+# At the date of writing these commands are: set setnx setex append
+# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+# getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+# in order to try to give an advantage to the slave with the best
+# replication offset (more data from the master processed).
+# Slaves will try to get their rank by offset, and apply to the start
+# of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+# its master. This can be the last ping or command received (if the master
+# is still in the "connected" state), or the time that elapsed since the
+# disconnection with the master (if the replication link is currently down).
+# If the last interaction is too old, the slave will not try to failover
+# at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+# (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+# K Keyspace events, published with __keyspace@<db>__ prefix.
+# E Keyevent events, published with __keyevent@<db>__ prefix.
+# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+# $ String commands
+# l List commands
+# s Set commands
+# h Hash commands
+# z Sorted set commands
+# x Expired events (events generated every time a key expires)
+# e Evicted events (events generated when a key is evicted for maxmemory)
+# A Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+# The "notify-keyspace-events" takes as argument a string that is composed
+# of zero or multiple characters. The empty string means that notifications
+# are disabled.
+#
+# Example: to enable list and generic events, from the point of view of the
+# event name, use:
+#
+# notify-keyspace-events Elg
+#
+# Example 2: to get the stream of the expired keys subscribing to channel
+# name __keyevent@0__:expired use:
+#
+# notify-keyspace-events Ex
+#
+# By default all notifications are disabled because most users don't need
+# this feature and the feature has some overhead. Note that if you don't
+# specify at least one of K or E, no events will be delivered.
+notify-keyspace-events ""
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Lists are also encoded in a special way to save a lot of space.
+# The number of entries allowed per internal list node can be specified
+# as a fixed maximum size or a maximum number of elements.
+# For a fixed maximum size, use -5 through -1, meaning:
+# -5: max size: 64 Kb <-- not recommended for normal workloads
+# -4: max size: 32 Kb <-- not recommended
+# -3: max size: 16 Kb <-- probably not recommended
+# -2: max size: 8 Kb <-- good
+# -1: max size: 4 Kb <-- good
+# Positive numbers mean store up to _exactly_ that number of elements
+# per list node.
+# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
+# but if your use case is unique, adjust the settings as necessary.
+list-max-ziplist-size -2
+
+# Lists may also be compressed.
+# Compress depth is the number of quicklist ziplist nodes from *each* side of
+# the list to *exclude* from compression. The head and tail of the list
+# are always uncompressed for fast push/pop operations. Settings are:
+# 0: disable all list compression
+# 1: depth 1 means "don't start compressing until after 1 node into the list,
+# going from either the head or tail"
+# So: [head]->node->node->...->node->[tail]
+# [head], [tail] will always be uncompressed; inner nodes will compress.
+# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
+# 2 here means: don't compress head or head->next or tail->prev or tail,
+# but compress all nodes between them.
+# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
+# etc.
+list-compress-depth 0
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeot, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are perforemd with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here. This is useful if you
+# have a standard template that goes to all Redis server but also need
+# to customize a few per-server settings. Include files can include
+# other files, so use this wisely.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
--
Gitblit v1.9.3