Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
e110d9e2
Commit
e110d9e2
authored
Mar 09, 2023
by
Vitaly Arbuzov
Browse files
Limit number of dictionaries that can be resized in one cron iteration
parent
7313244d
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/db.c
View file @
e110d9e2
...
...
@@ -535,6 +535,7 @@ long long emptyDbStructure(redisDb *dbarray, int dbnum, int async,
/* Because all keys of database are removed, reset average ttl. */
dbarray
[
j
].
avg_ttl
=
0
;
dbarray
[
j
].
expires_cursor
=
0
;
dbarray
[
j
].
resize_cursor
=
0
;
dbarray
[
j
].
key_count
=
0
;
zfree
(
dbarray
[
j
].
non_empty_dicts
);
dbarray
[
j
].
non_empty_dicts
=
intsetNew
();
...
...
@@ -1568,6 +1569,7 @@ int dbSwapDatabases(int id1, int id2) {
db1
->
expires
=
db2
->
expires
;
db1
->
avg_ttl
=
db2
->
avg_ttl
;
db1
->
expires_cursor
=
db2
->
expires_cursor
;
db1
->
resize_cursor
=
db2
->
resize_cursor
;
db1
->
dict_count
=
db2
->
dict_count
;
db1
->
key_count
=
db2
->
key_count
;
db1
->
non_empty_dicts
=
db2
->
non_empty_dicts
;
...
...
@@ -1576,6 +1578,7 @@ int dbSwapDatabases(int id1, int id2) {
db2
->
expires
=
aux
.
expires
;
db2
->
avg_ttl
=
aux
.
avg_ttl
;
db2
->
expires_cursor
=
aux
.
expires_cursor
;
db2
->
resize_cursor
=
aux
.
resize_cursor
;
db2
->
dict_count
=
aux
.
dict_count
;
db2
->
key_count
=
aux
.
key_count
;
db2
->
non_empty_dicts
=
aux
.
non_empty_dicts
;
...
...
@@ -1616,6 +1619,7 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
activedb
->
expires
=
newdb
->
expires
;
activedb
->
avg_ttl
=
newdb
->
avg_ttl
;
activedb
->
expires_cursor
=
newdb
->
expires_cursor
;
activedb
->
resize_cursor
=
newdb
->
resize_cursor
;
activedb
->
dict_count
=
newdb
->
dict_count
;
activedb
->
key_count
=
newdb
->
key_count
;
activedb
->
non_empty_dicts
=
newdb
->
non_empty_dicts
;
...
...
@@ -1624,6 +1628,7 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
newdb
->
expires
=
aux
.
expires
;
newdb
->
avg_ttl
=
aux
.
avg_ttl
;
newdb
->
expires_cursor
=
aux
.
expires_cursor
;
newdb
->
resize_cursor
=
aux
.
resize_cursor
;
newdb
->
dict_count
=
aux
.
dict_count
;
newdb
->
key_count
=
aux
.
key_count
;
newdb
->
non_empty_dicts
=
aux
.
non_empty_dicts
;
...
...
src/server.c
View file @
e110d9e2
...
...
@@ -590,13 +590,20 @@ int htNeedsResize(dict *dict) {
void
tryResizeHashTables
(
int
dbid
)
{
dict
*
d
;
dbIterator
dbit
;
dbIteratorInit
(
&
dbit
,
&
server
.
db
[
dbid
]);
while
((
d
=
dbIteratorNextDict
(
&
dbit
)))
{
redisDb
*
db
=
&
server
.
db
[
dbid
];
dbIteratorInit
(
&
dbit
,
db
);
dbit
.
index
=
db
->
resize_cursor
;
for
(
int
i
=
0
;
i
<
CRON_DICTS_PER_CALL
;
i
++
)
{
d
=
dbIteratorNextDict
(
&
dbit
);
if
(
d
==
NULL
)
break
;
if
(
htNeedsResize
(
d
))
dictResize
(
d
);
}
if
(
htNeedsResize
(
server
.
db
[
dbid
].
expires
))
dictResize
(
server
.
db
[
dbid
].
expires
);
/* Save current index in the resize cursor, or start over if we've reached the end.*/
db
->
resize_cursor
=
dbit
.
cur_slot
==
-
1
?
0
:
dbit
.
index
;
if
(
htNeedsResize
(
db
->
expires
))
dictResize
(
db
->
expires
);
}
/* Our hash table implementation performs rehashing incrementally while
...
...
@@ -2584,6 +2591,7 @@ void initServer(void) {
server
.
db
[
j
].
dict
=
dictCreateMultiple
(
&
dbDictType
,
slotCount
);
server
.
db
[
j
].
expires
=
dictCreate
(
&
dbExpiresDictType
);
server
.
db
[
j
].
expires_cursor
=
0
;
server
.
db
[
j
].
resize_cursor
=
0
;
server
.
db
[
j
].
blocking_keys
=
dictCreate
(
&
keylistDictType
);
server
.
db
[
j
].
blocking_keys_unblock_on_nokey
=
dictCreate
(
&
objectKeyPointerValueDictType
);
server
.
db
[
j
].
ready_keys
=
dictCreate
(
&
objectKeyPointerValueDictType
);
...
...
src/server.h
View file @
e110d9e2
...
...
@@ -115,6 +115,7 @@ typedef struct redisObject robj;
#define CONFIG_MAX_HZ 500
#define MAX_CLIENTS_PER_CLOCK_TICK 200
/* HZ is adapted based on that. */
#define CRON_DBS_PER_CALL 16
#define CRON_DICTS_PER_CALL 1024
/* Number of dictionaries that can be resized by cron job during one call. */
#define NET_MAX_WRITES_PER_EVENT (1024*64)
#define PROTO_SHARED_SELECT_CMDS 10
#define OBJ_SHARED_INTEGERS 10000
...
...
@@ -946,7 +947,7 @@ typedef struct replBufBlock {
* by integers from 0 (the default database) up to the max configured
* database. The database number is the 'id' field in the structure. */
typedef
struct
redisDb
{
dict
**
dict
;
/* The keyspace for this DB */
dict
**
dict
;
/* The keyspace for this DB */
dict
*
expires
;
/* Timeout of keys with a timeout set */
dict
*
blocking_keys
;
/* Keys with clients waiting for data (BLPOP)*/
dict
*
blocking_keys_unblock_on_nokey
;
/* Keys with clients waiting for
...
...
@@ -957,11 +958,12 @@ typedef struct redisDb {
int
id
;
/* Database ID */
long
long
avg_ttl
;
/* Average TTL, just for stats */
unsigned
long
expires_cursor
;
/* Cursor of the active expire cycle. */
int
resize_cursor
;
/* Cron job uses this cursor to gradually resize dictionaries. */
list
*
defrag_later
;
/* List of key names to attempt to defrag one by one, gradually. */
list
*
rehashing
;
/* List of dictionaries in this DB that are currently rehashing. */
int
dict_count
;
/* Indicates total number of dictionaires owned by this DB, 1 dict per slot in cluster mode. */
unsigned
long
long
key_count
;
/* Total number of keys in this DB. */
intset
*
non_empty_dicts
;
/* Set of non-empty dictionaries. */
intset
*
non_empty_dicts
;
/* Set of non-empty dictionaries. */
}
redisDb
;
/* forward declaration for functions ctx */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment