diff options
author | zhaozhao.zz <zhaozhao.zz@alibaba-inc.com> | 2018-09-04 00:02:18 +0800 |
---|---|---|
committer | zhaozhao.zz <zhaozhao.zz@alibaba-inc.com> | 2018-09-04 00:02:25 +0800 |
commit | 247d2a734b0434e0f461902f64d32cb6e587709c (patch) | |
tree | 14a3913b70d91e55d65709939c92d6e2269b9e93 | |
parent | febe102bf6d94428779f3943aea5947893301912 (diff) | |
download | redis-247d2a734b0434e0f461902f64d32cb6e587709c.tar.gz |
networking: optimize parsing large bulk greater than 32k
If we are going to read a large object from network
try to make it likely that it will start at c->querybuf
boundary so that we can optimize object creation
avoiding a large copy of data.
But only when the data we have not parsed is less than
or equal to ll+2. If the data length is greater than
ll+2, trimming querybuf is just a waste of time, because
at this time the querybuf contains not only our bulk.
It's easy to reproduce the that:
Time1: call `client pause 10000` on slave.
Time2: redis-benchmark -t set -r 10000 -d 33000 -n 10000.
Then slave hung after 10 seconds.
-rw-r--r-- | src/networking.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/networking.c b/src/networking.c index 27c695306..eac94798c 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1294,19 +1294,22 @@ int processMultibulkBuffer(client *c) { c->qb_pos = newline-c->querybuf+2; if (ll >= PROTO_MBULK_BIG_ARG) { - size_t qblen; - /* If we are going to read a large object from network * try to make it likely that it will start at c->querybuf * boundary so that we can optimize object creation - * avoiding a large copy of data. */ - sdsrange(c->querybuf,c->qb_pos,-1); - c->qb_pos = 0; - qblen = sdslen(c->querybuf); - /* Hint the sds library about the amount of bytes this string is - * going to contain. */ - if (qblen < (size_t)ll+2) - c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2-qblen); + * avoiding a large copy of data. + * + * But only when the data we have not parsed is less than + * or equal to ll+2. If the data length is greater than + * ll+2, trimming querybuf is just a waste of time, because + * at this time the querybuf contains not only our bulk. */ + if (sdslen(c->querybuf)-c->qb_pos <= (size_t)ll+2) { + sdsrange(c->querybuf,c->qb_pos,-1); + c->qb_pos = 0; + /* Hint the sds library about the amount of bytes this string is + * going to contain. */ + c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2); + } } c->bulklen = ll; } |