summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-09-04 00:02:18 +0800
committerzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2018-09-04 00:02:25 +0800
commit247d2a734b0434e0f461902f64d32cb6e587709c (patch)
tree14a3913b70d91e55d65709939c92d6e2269b9e93
parentfebe102bf6d94428779f3943aea5947893301912 (diff)
downloadredis-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.c23
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;
}