Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xindoo
redis
提交
0edd38e5
R
redis
项目概览
xindoo
/
redis
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
0edd38e5
编写于
12月 25, 2012
作者:
Y
Yossi Gottlieb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add minmemory-os configuration parameter.
上级
e4375727
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
99 addition
and
7 deletion
+99
-7
redis.conf
redis.conf
+6
-0
src/config.c
src/config.c
+3
-1
src/redis.c
src/redis.c
+87
-4
src/redis.h
src/redis.h
+2
-1
src/scripting.c
src/scripting.c
+1
-1
未找到文件。
redis.conf
浏览文件 @
0edd38e5
...
...
@@ -322,6 +322,12 @@ slave-priority 100
#
# maxmemory-samples 3
# Define the minimum OS memory threshold allowed before eviction begins. This
# is checked perioedically and eviction will be attempted for 1/2 of the delta
# between the free memory and required spare. If 0 is specified, this is
# disabled.
# minmemory-os 0
############################## APPEND ONLY MODE ###############################
# By default Redis asynchronously dumps the dataset on disk. This mode is
...
...
src/config.c
浏览文件 @
0edd38e5
...
...
@@ -197,6 +197,8 @@ void loadServerConfigFromString(char *config) {
}
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"maxmemory"
)
&&
argc
==
2
)
{
server
.
maxmemory
=
memtoll
(
argv
[
1
],
NULL
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"minmemory-os"
)
&&
argc
==
2
)
{
server
.
minmemory_os
=
memtoll
(
argv
[
1
],
NULL
);
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"maxmemory-policy"
)
&&
argc
==
2
)
{
if
(
!
strcasecmp
(
argv
[
1
],
"volatile-lru"
))
{
server
.
maxmemory_policy
=
REDIS_MAXMEMORY_VOLATILE_LRU
;
...
...
@@ -493,7 +495,7 @@ void configSetCommand(redisClient *c) {
if
(
server
.
maxmemory
<
zmalloc_used_memory
())
{
redisLog
(
REDIS_WARNING
,
"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in keys eviction and/or inability to accept new write commands depending on the maxmemory-policy."
);
}
freeMemoryIfNeeded
();
freeMemoryIfNeeded
(
server
.
maxmemory
);
}
}
else
if
(
!
strcasecmp
(
c
->
argv
[
2
]
->
ptr
,
"maxmemory-policy"
))
{
if
(
!
strcasecmp
(
o
->
ptr
,
"volatile-lru"
))
{
...
...
src/redis.c
浏览文件 @
0edd38e5
...
...
@@ -794,6 +794,84 @@ void clientsCron(void) {
}
}
#ifdef __linux__
long
long
int
getFreeOSMemory
(
void
)
{
FILE
*
meminfo_file
;
char
buf
[
128
];
long
long
int
memfree_value
=
-
1
;
long
long
int
buffers_value
=
-
1
;
long
long
int
cached_value
=
-
1
;
long
long
int
memfree
=
-
1
;
meminfo_file
=
fopen
(
"/proc/meminfo"
,
"r"
);
if
(
!
meminfo_file
)
return
-
1
;
while
(
fgets
(
buf
,
sizeof
(
buf
)
-
1
,
meminfo_file
)
!=
NULL
)
{
char
*
p
=
NULL
;
char
*
k
;
char
*
arg
;
if
(
!
(
k
=
strtok_r
(
buf
,
" "
,
&
p
)))
break
;
/* parse error */
if
(
!
(
arg
=
strtok_r
(
NULL
,
" "
,
&
p
)))
break
;
/* parse error */
if
(
strcmp
(
k
,
"MemFree:"
)
==
0
)
{
memfree_value
=
strtoull
(
arg
,
&
p
,
10
);
if
(
!
p
||
*
p
!=
'\0'
)
memfree_value
=
-
1
;
/* parse error */
}
else
if
(
strcmp
(
k
,
"Buffers:"
)
==
0
)
{
buffers_value
=
strtoull
(
arg
,
&
p
,
10
);
if
(
!
p
||
*
p
!=
'\0'
)
buffers_value
=
-
1
;
/* parse error */
}
else
if
(
strcmp
(
k
,
"Cached:"
)
==
0
)
{
cached_value
=
strtoull
(
arg
,
&
p
,
10
);
if
(
!
p
||
*
p
!=
'\0'
)
cached_value
=
-
1
;
/* parse error */
}
if
(
memfree_value
!=
-
1
&&
buffers_value
!=
-
1
&&
cached_value
!=
-
1
)
{
memfree
=
memfree_value
+
buffers_value
+
cached_value
;
break
;
}
}
fclose
(
meminfo_file
);
if
(
memfree
>
0
)
memfree
*=
1024
;
return
memfree
;
}
#else
#error "Implement getFreeOSMemory for this platform first."
#endif
void
checkOSMemory
(
void
)
{
/* Called periodically if minmemory_os is defined, and verifies that
* enough free OS memory is reported. If not, it attempts to free 1/2
* of the minmemory_os value.
*/
long
long
int
os_memfree
;
if
(
!
server
.
minmemory_os
)
return
;
os_memfree
=
getFreeOSMemory
();
if
(
os_memfree
<
0
)
return
;
if
((
unsigned
long
long
)
os_memfree
<
server
.
minmemory_os
)
{
long
long
int
delta
=
server
.
minmemory_os
-
os_memfree
;
if
((
long
long
int
)
zmalloc_used_memory
()
>
(
delta
/
2
))
{
redisLog
(
REDIS_WARNING
,
"OS Memory is low, trying to free %llu bytes."
,
delta
/
2
);
freeMemoryIfNeeded
(
zmalloc_used_memory
()
-
(
delta
/
2
));
}
else
{
redisLog
(
REDIS_WARNING
,
"OS Memory is low, but this redis is too small to attempt eviction."
);
}
}
}
/* This is our timer interrupt, called REDIS_HZ times per second.
* Here is where we do a number of things that need to be done asynchronously.
* For instance:
...
...
@@ -856,6 +934,11 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
redisLog
(
REDIS_WARNING
,
"SIGTERM received but errors trying to shut down the server, check the logs for more information"
);
}
/* Try to evict if OS memory is low */
run_with_period
(
10000
)
{
checkOSMemory
();
}
/* Cancel draining mode if not polled for a long time */
if
(
server
.
draining
&&
server
.
unixtime
-
server
.
last_drain_time
>=
10
)
server
.
draining
=
0
;
...
...
@@ -1636,7 +1719,7 @@ int processCommand(redisClient *c) {
* keys in the dataset). If there are not the only thing we can do
* is returning an error. */
if
(
server
.
maxmemory
)
{
int
retval
=
freeMemoryIfNeeded
();
int
retval
=
freeMemoryIfNeeded
(
server
.
maxmemory
);
if
((
c
->
cmd
->
flags
&
REDIS_CMD_DENYOOM
)
&&
retval
==
REDIS_ERR
)
{
flagTransaction
(
c
);
addReply
(
c
,
shared
.
oomerr
);
...
...
@@ -2321,7 +2404,7 @@ void hideconnectionCommand(redisClient *c) {
* should block the execution of commands that will result in more memory
* used by the server.
*/
int
freeMemoryIfNeeded
(
void
)
{
int
freeMemoryIfNeeded
(
unsigned
long
long
maxmemory
)
{
size_t
mem_used
,
mem_tofree
,
mem_freed
;
int
slaves
=
listLength
(
server
.
slaves
);
...
...
@@ -2348,13 +2431,13 @@ int freeMemoryIfNeeded(void) {
}
/* Check if we are over the memory limit. */
if
(
mem_used
<=
server
.
maxmemory
)
return
REDIS_OK
;
if
(
mem_used
<=
maxmemory
)
return
REDIS_OK
;
if
(
server
.
maxmemory_policy
==
REDIS_MAXMEMORY_NO_EVICTION
)
return
REDIS_ERR
;
/* We need to free memory, but policy forbids. */
/* Compute how much memory we need to free. */
mem_tofree
=
mem_used
-
server
.
maxmemory
;
mem_tofree
=
mem_used
-
maxmemory
;
mem_freed
=
0
;
while
(
mem_freed
<
mem_tofree
)
{
int
j
,
k
,
keys_freed
=
0
;
...
...
src/redis.h
浏览文件 @
0edd38e5
...
...
@@ -650,6 +650,7 @@ struct redisServer {
/* Limits */
unsigned
int
maxclients
;
/* Max number of simultaneous clients */
unsigned
long
long
maxmemory
;
/* Max number of memory bytes to use */
unsigned
long
long
minmemory_os
;
/* OS Free memory threshold that */
int
maxmemory_policy
;
/* Policy for key evition */
int
maxmemory_samples
;
/* Pricision of random sampling */
/* Blocked clients */
...
...
@@ -969,7 +970,7 @@ unsigned int zsetLength(robj *zobj);
void
zsetConvert
(
robj
*
zobj
,
int
encoding
);
/* Core functions */
int
freeMemoryIfNeeded
(
void
);
int
freeMemoryIfNeeded
(
unsigned
long
long
maxmemory
);
int
processCommand
(
redisClient
*
c
);
void
setupSignalHandlers
(
void
);
struct
redisCommand
*
lookupCommand
(
sds
name
);
...
...
src/scripting.c
100644 → 100755
浏览文件 @
0edd38e5
...
...
@@ -278,7 +278,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if
(
server
.
maxmemory
&&
server
.
lua_write_dirty
==
0
&&
(
cmd
->
flags
&
REDIS_CMD_DENYOOM
))
{
if
(
freeMemoryIfNeeded
()
==
REDIS_ERR
)
{
if
(
freeMemoryIfNeeded
(
server
.
maxmemory
)
==
REDIS_ERR
)
{
luaPushError
(
lua
,
shared
.
oomerr
->
ptr
);
goto
cleanup
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录