Redis is easy to use. Do you know what protocol it uses?

InfoQ 2021-01-14 17:29:01
redis easy use. use know


{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I'm a kite , official account 「 Ancient kites 」, A programmer encourager with both depth and breadth , An idyllic code farmer who was going to write poetry ! The article will be included in ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/huzhicheng/JavaNewBee","title":""},"content":[{"type":"text","text":"JavaNewBee","attrs":{}}]},{"type":"text","text":" in , What's more Java Back end knowledge map , The road from Xiaobai to Daniel is in it .","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" A little friend came back from the interview and said that the interviewer asked him some Redis problem , But he didn't seem to answer .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I said, , you Redis Isn't it very smooth to use , What's bothering you .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" He said , Here's the thing , At first , Asked some basic questions , such as Redis Several basic data types and usage scenarios of , And some problems of master-slave replication and clustering , These are all OK .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then ask Redis Two ways to persist , I said that RDB and AOF Two ways ,RDB Data file size , Fast recovery , But it has an impact on performance , And it's not suitable for real-time storage . and AOF It's the most common way to persist now , One of its great advantages is real-time , And right Redis Half body performance has the least effect .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then the interview asked again , You know, AOF What format is the file after persistence ?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" answer : It seems to be a text file ?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" good , text file , Do you know what the rules are ? Or say , It and Redis What's the matter with the agreement ?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" answer : ah , This , Okay , I'm not sure .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Now let's take a look at AOF and RESP Relationship of agreement ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":" Let's start with two persistence methods .","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"RESP What is the protocol ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":" Start to implement a simple protocol parsing command line tool ","attrs":{}}]}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/16/1605085882b1b4e7d08728c51871f047.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Let's start with persistence , Although the mention of Redis, The first thing I think about is caching , however Redis It's not just caching , Its location is memory database , Can store multiple types of data structures , It can also be used as a simple message queue . Since it's a database , Persistence is essential .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Redis Two ways to persist ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis There are two ways to persist , One is RDB The way , The other is AOF The way ,AOF It is a popular persistence scheme at present .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"RDB The way ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Persistence is through snapshots , Write the data set snapshot in memory to disk within the specified time interval . It comes in the form of a compact compressed binary file . You can copy a snapshot to another server to create a server copy of the same data , Or recover the data after restarting the server .RDB yes Redis Default persistence method , It's also a must for earlier versions .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Controlled by the following parameters .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# Set up dump The name of the file \ndbfilename dump.rdb\n\n# The directory where persistent files are stored \ndir ./\n\n# 900 Seconds , If at least 1 individual key change , Will trigger automatically bgsave Command create snapshot \nsave 900 1\n\n# 300 Seconds , If at least 10 individual key change , Will trigger automatically bgsave Command create snapshot \nsave 300 10\n\n# 60 Seconds , If at least 10000 individual key change , Will trigger automatically bgsave Command create snapshot \nsave 60 10000","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Persistence process ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I mentioned several mechanisms in the configuration file that trigger persistence , such as 900 second 、300 second 、60 second , You can also execute commands manually ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"save","attrs":{}}],"attrs":{}},{"type":"text","text":" or ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"bgsave","attrs":{}}],"attrs":{}},{"type":"text","text":" Trigger .","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"bgsave","attrs":{}}],"attrs":{}},{"type":"text","text":" It's a non blocking version , adopt fork The method of sub process is used to generate snapshot , and ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"save","attrs":{}}],"attrs":{}},{"type":"text","text":" Will block the main process , Not recommended .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、 First ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"bgsave","attrs":{}}],"attrs":{}},{"type":"text","text":" Command trigger ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、 The parent process fork Make a sub process , This step is a more heavyweight operation , It's also RDB The performance of the method is not as good as AOF An important reason for ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、 The parent process fork Out of the child process can be normal after the corresponding client sent other commands ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、 The child process begins to do persistence work , Complete snapshot storage of existing data ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5、 After the child process has completed its operation , Notify the parent process ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/60/601916a14a477438c18c80c58935e5d8.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"RDB The advantages of :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Is a compact binary , representative Redis Data at a certain point in time snapshot . Ideal for backup , Full scale replication and other scenarios . Like every 6 Hours to perform bgsave Backup , And put RDB Copy files to a remote machine or file system ( Such as hdfs), For disaster recovery .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis load RDB Recover data much faster than AOF The way .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"RDB The shortcomings of :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Modal data cannot be persisted in real time / Second persistence . because bgsave Every time All trades must be carried out fork Action create subprocess , Is a heavyweight operation , Frequent execution cost is too high .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Files are saved in a specific binary format ,Redis There are multiple formats in the version evolution process Of RDB edition , There is an old version Redis The service is not compatible with the new version RDB The problem of format .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"AOF The way ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"AOF Controlled by the following parameters .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"# appendonly Parameter on AOF Persistence \nappendonly yes\n\n# AOF Persistent filename , The default is appendonly.aof\nappendfilename \"appendonly.aof\"\n\n# AOF The location and RDB The location of the files is the same , It's all through dir Parameter setting \ndir ./\n\n# Synchronization strategies \n# appendfsync always\nappendfsync everysec\n# appendfsync no\n\n# aof Synchronization during rewrite \nno-appendfsync-on-rewrite no\n\n# Override trigger configuration \nauto-aof-rewrite-percentage 100\nauto-aof-rewrite-min-size 64mb\n\n# load aof How to deal with mistakes \naof-load-truncated yes\n\n# File rewrite strategy \naof-rewrite-incremental-fsync yes","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" in the light of RDB Problems that are not suitable for real-time persistence ,Redis Provides AOF Persistent way to solve ,AOF It's also the most current way to persist .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"AOF(append only file), Each write is logged as a separate log , Reexecute on reboot AOF The command in the file restores the data .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、 All write commands are appended to aof_buf( buffer ) in ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、AOF The buffer synchronizes the hard disk according to the corresponding policy ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、 With AOF The files are getting bigger , It needs to be done regularly AOF File rewriting , Achieve the purpose of compression ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、 When Redis When the server restarts , Can be loaded AOF File for data recovery ;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6f/6faff0d48bc5b589b31a2587adb96335.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"AOF What's in the file ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I tested it locally redis There are a few commands in the environment , Then open the appendonly.aof The file to view , It turns out that it looks like this .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/be/bef404985f5185f3d486cfab89ea6fb5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"RESP agreement ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis The client communicates with the server , Use RESP Protocol communication , The agreement is specifically for Redis Designed communication protocol , But it can also be used for other clients - Server communication scenarios .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RESP The agreement has the following characteristics :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Implement a simple ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Fast parsing ;","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Can be read ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The client sends commands to the server , After the server gets the command, it parses it , Then execute the corresponding logic , And then back to the client , Yes, of course , This post and reply are all used RESP The format of the protocol features .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" We usually use ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"redis-cli","attrs":{}}],"attrs":{}},{"type":"text","text":" Or some client tools to connect to Redis Server side .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"./redis-cli","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then, the commands of the whole interaction process send and return the results as follows , The green part is the command sent , The red part is the returned result .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/df/df4cc3825f0f1bd8beda6dd5729b1ac5.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" That's what we're all familiar with . however , It doesn't show that RESP The real face of the agreement .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" use telnet try ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RESP Is based on TCP Protocol implemented , So in addition to using various client tools and Redis Provided ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"redis-cli","attrs":{}}],"attrs":{}},{"type":"text","text":" Tools , You can also use telnet see , use telnet We can see that RESP The returned original data format is .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I'm a local Redis By default 6379 port , And no settings requirepass , Let's try to use telnet Connect .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"telnet 127.0.0.1 6379","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then execute the same commands as before , The results of sending and returning are as follows , The green part is the command sent , Red is the returned result .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a6/a6f8aa8a136a2d9407ec7fe4a203c512.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" What about? , Some command returns are OK , But like ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"get str:hello","attrs":{}}],"attrs":{}},{"type":"text","text":" This article , The result returned is in addition to ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"world","attrs":{}}],"attrs":{}},{"type":"text","text":" Value itself , There's an extra line on it ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"$5","attrs":{}}],"attrs":{}},{"type":"text","text":", Isn't it a bit confusing .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Rules of agreement ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Request command ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The rules for a client to send a command to the server are as follows :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"*< The number of arguments > CR LF\n$< Parameters 1 Number of bytes > CR LF\n< Parameters 1 The data of > CR LF\n...\n$< Parameters N Number of bytes > CR LF\n< Parameters N The data of > CR LF","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RESP use ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\\r\\n","attrs":{}}],"attrs":{}},{"type":"text","text":" As a separator , It will indicate the number of specific parameters of this command , In terms of the order , All spaces separated represent a parameter , for example ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"set str:hello world","attrs":{}}],"attrs":{}},{"type":"text","text":" This order is 3 Parameters , The number of characters and the specific content of each parameter will be indicated .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Use this command as an example , Corresponding to RESP The rules of the agreement will look like this :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"*3\\r\\n$3\\r\\nset\\r\\n$9str:hello\\r\\n$5world\\r\\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8c/8cd556a6f75f232f04257a684e3ef386.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Server reply ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis The command returns a number of different types of replies .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" By checking the first byte of data the server sends back , Can you determine what type of response this is :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、 State the reply (status reply) The first byte of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\"+\"","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" such as ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ping","attrs":{}}],"attrs":{}},{"type":"text","text":" A reply to an order ,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"+PONG\\r\\n","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、 Error response (error reply) The first byte of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\"-\"","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" For example, enter a redis Commands that don't exist in , Or set the wrong parameters for some commands , For example, the input ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"auth","attrs":{}}],"attrs":{}},{"type":"text","text":",auth A password parameter is required after the command , If you don't type, the error reply type is returned .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-ERR wrong number of arguments for 'auth' command\\r\\n","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3、 Integer reply (integer reply) The first byte of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\":\"","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" for example ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"INCR","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DECR","attrs":{}}],"attrs":{}},{"type":"text","text":" Auto increment and auto decrement order , The result is like this ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":":2\\r\\n","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4、 Batch reply (bulk reply) The first byte of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\"$\"","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" For example string Type execution get operation ,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"$5\\r\\nworld\\r\\n","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"$","attrs":{}}],"attrs":{}},{"type":"text","text":" Back number 5 Indicates that the returned result is 5 Characters , After that is the actual content of the returned result .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5、 Multiple batch replies (multi bulk reply) The first byte of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"\"*\"","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" for example ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"LRANGE key start stop","attrs":{}}],"attrs":{}},{"type":"text","text":" perhaps ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"hgetall","attrs":{}}],"attrs":{}},{"type":"text","text":" Wait for the command to return multiple results , such as ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"lrange","attrs":{}}],"attrs":{}},{"type":"text","text":" Results returned by command :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"*2\\r\\n$6\\r\\nnews-2\\r\\n$6\\r\\nnews-1\\r\\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The format of multiple batch replies is the same as the previous client sending command .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Implement a simple one Redis Interactive tools ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I understand Redis The rules of agreement , We can write a simple client by ourselves . Of course , Through the official website, we can see that there are already various languages , And each language has more than one client tool .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/00/00ec950dc4168774a5d9bba12d2f89b2.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" such as Java There are so many kinds of language clients , among Jedis It should be used most , Now that there are such good wheels , Of course, there's no need to make wheels again , Mainly to deepen the impression .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/4a/4a1baac531c7644f0f7671d53ce2f51e.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RESP Based on the agreement TCP agreement , have access to socket Way to connect .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public Socket createSocket() throws IOException {\n Socket socket = null;\n try {\n socket = new Socket();\n socket.setReuseAddress(true);\n socket.setKeepAlive(true);\n socket.setTcpNoDelay(true);\n socket.setSoLinger(true, 0);\n\n socket.connect(new InetSocketAddress(host, port), DEFAULT_TIMEOUT);\n socket.setSoTimeout(DEFAULT_TIMEOUT);\n outputStream = socket.getOutputStream();\n inputStream = socket.getInputStream();\n return socket;\n } catch (Exception ex) {\n if (socket != null) {\n socket.close();\n }\n throw ex;\n }\n}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then the rest is to return the result of string parsing , The tools I've made are as simple as this , Here is the return output of some simple commands .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d3/d3879c16d3d541ddb6e7a7f5b3e075d1.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The code has been put into github On , Those who are interested can clone Come down and have a look .","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://github.com/huzhicheng/medis","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" This handsome young man , If it's not bad , How about a recommendation !","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" official account 「 Ancient kites 」,Java developer , Full stack engineer ,bug killer , Good at solving problems .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" A programmer encourager with both depth and breadth , The idyllic code farmer who had intended to write poetry ! Adhere to the original dry goods output , You can choose to focus on me now , Or take a look at historical articles, and it's never too late to pay attention to them . Long press QR code to focus on , Be good with me !","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6e/6ee26f519a5119e44cf672106e63caa2.jpeg","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210114172452472r.html

  1. Learn about RPC, why RPC was born, and what's the difference between RPC and HTTP?
  2. Learn about RPC, why RPC was born, and what's the difference between RPC and HTTP?
  3. Learn java base conversion supplementary learning
  4. JDBC测试连接数据库
  5. JDBC test connection database
  6. 大厂面试官竟然这么爱问Kafka,一连八个Kafka问题把我问蒙了?
  7. The interviewers of big factories love to ask Kafka so much. I'm blinded by eight Kafka questions in a row?
  8. 安卓开发和java开发有什么区别!2021年BATJ30套大厂Android经典高频面试题,面试必问
  9. Spring Security OAuth2.0認證授權四:分散式系統認證授權
  10. What's the difference between Android development and java development! 2021 batj30 Android classic high frequency interview questions
  11. Spring security oauth2.0 authentication and authorization 4: distributed system authentication and authorization
  12. Java微服务 vs Go微服务,究竟谁更强!?
  13. 大厂面试官竟然这么爱问Kafka,一连八个Kafka问题把我问蒙了?
  14. Who is stronger, Java microservice vs go microservice!?
  15. Java微服务 vs Go微服务,究竟谁更强!?
  16. The interviewers of big factories love to ask Kafka so much. I'm blinded by eight Kafka questions in a row?
  17. Who is stronger, Java microservice vs go microservice!?
  18. springboot异常处理之404
  19. Spring boot exception handling 404
  20. Spring Boot Security 国际化 多语言 i18n 趟过巨坑
  21. springboot异常处理之404
  22. Spring boot security international multilingual I18N
  23. Spring boot exception handling 404
  24. Netty系列化之Google Protobuf编解码
  25. Netty之编解码
  26. Java编解码
  27. Netty解码器
  28. Netty与TCP粘包拆包
  29. Netty开发入门
  30. Java集合遍历时遇到的坑
  31. Spring IOC 源码解析(下)
  32. Spring IoC源码解析(上)
  33. Google protobuf codec of netty serialization
  34. Encoding and decoding of netty
  35. Java codec
  36. Netty decoder
  37. Netty and TCP packet sticking and unpacking
  38. Introduction to netty development
  39. Problems encountered in Java collection traversal
  40. Spring IOC source code analysis (2)
  41. Spring IOC source code analysis (Part one)
  42. 半小时用Spring Boot注解实现Redis分布式锁
  43. Implementing redis distributed lock with spring boot annotation in half an hour
  44. What should we do if we can't get tickets for Spring Festival transportation? You can solve this problem by using these ticket grabbing apps!
  45. 百度智能(文本识别),API传图OC代码与SDK使用
  46. springboot源码解析-管中窥豹系列之aware(六)
  47. Baidu intelligent (text recognition), API map, OC code and SDK
  48. Spring boot source code analysis
  49. springboot源码解析-管中窥豹系列之aware(六)
  50. 百度智能(文本识别),API传图OC代码与SDK使用
  51. Spring boot source code analysis
  52. Baidu intelligent (text recognition), API map, OC code and SDK
  53. Java学习笔记
  54. Java learning notes
  55. Sentry(v20.12.1) K8S 雲原生架構探索, SENTRY FOR JAVASCRIPT 手動捕獲事件基本用法
  56. 我的程式設計師之路:自學Java篇
  57. SpringBoot專案,如何優雅的把介面引數中的空白值替換為null值?
  58. Sentry (v20.12.1) k8s cloud native architecture exploration, sentry for JavaScript manual capture event basic usage
  59. My way of programmer: self study java
  60. Spring boot project, how to gracefully replace the blank value in the interface argument with null value?