{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The previous article introduced Redis The related use and underlying principles of simple data structure of , Let's talk about this article Redis How to ensure high availability ."}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Data persistence "}]},{"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 know that although the single machine Redis Although the performance is excellent , A single machine can carry it 10w Of QPS, This is due to its memory based fast read and write operations , Well, if at some time Redis What should I do if I hang up suddenly ? We need a "},{"type":"text","marks":[{"type":"strong"}],"text":" Persistence "},{"type":"text","text":" The mechanism of , To save data in memory , Otherwise, the data will be directly lost ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis There are two ways to achieve data persistence , Namely "},{"type":"text","marks":[{"type":"strong"}],"text":"RDB"},{"type":"text","text":"(Redis Database) and "},{"type":"text","marks":[{"type":"strong"}],"text":"AOF"},{"type":"text","text":"(Append Only File), You can simply put RDB Understood as a moment Redis Data snapshot in memory , and AOF It is a collection of all instructions that record all changes to memory data ( That is to say Redis Set of instructions ), And these two methods will generate the corresponding file to the disk , Data persistence , Convenient for the next time ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Let's talk about these two persistence schemes respectively ."}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"RDB"}]},{"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":" stay redis In the middle of RDB There are two ways to take a snapshot , One is to use "},{"type":"codeinline","content":[{"type":"text","text":"save"}]},{"type":"text","text":", The other is "},{"type":"codeinline","content":[{"type":"text","text":"bgsave"}]},{"type":"text","text":", But the underlying implementation , It calls the same function , It's called "},{"type":"codeinline","content":[{"type":"text","text":"rdbsave"}]},{"type":"text","text":", It's just that it's called in a different way ."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Generation method "}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"save"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"save The command calls directly "},{"type":"codeinline","content":[{"type":"text","text":"rdbsave"}]},{"type":"text","text":" Method , This will "},{"type":"text","marks":[{"type":"strong"}],"text":" Blocking Redis The main process "},{"type":"text","text":", Until the snapshot file is generated ."}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"void saveCommand(client *c) {\n if (server.rdb_child_pid != -1) {\n addReplyError(c,\"Background save already in progress\");\n return;\n }\n rdbSaveInfo rsi, *rsiptr;\n rsiptr = rdbPopulateSaveInfo(&rsi);\n if (rdbSave(server.rdb_filename,rsiptr) == C_OK) {\n addReply(c,shared.ok);\n } else {\n addReply(c,shared.err);\n }\n}\n"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"bgsave"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"bgsave Orders will fork Make a sub process , from fork Out of the subprocess call "},{"type":"codeinline","content":[{"type":"text","text":"rdbsave"}]},{"type":"text","text":". The parent process will continue to respond to read and write requests from the client . Subprocess complete RDB After the file is generated, it will send a signal to the parent process , Notifies the parent process that the save is complete ."}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"/* BGSAVE [SCHEDULE] */\nvoid bgsaveCommand(client *c) {\n int schedule = 0;\n\n /* The SCHEDULE option changes the behavior of BGSAVE when an AOF rewrite\n * is in progress. Instead of returning an error a BGSAVE gets scheduled. */\n if (c->argc > 1) {\n if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,\"schedule\")) {\n schedule = 1;\n } else {\n addReply(c,shared.syntaxerr);\n return;\n }\n }\n\n rdbSaveInfo rsi, *rsiptr;\n rsiptr = rdbPopulateSaveInfo(&rsi);\n\n if (server.rdb_child_pid != -1) {\n addReplyError(c,\"Background save already in progress\");\n } else if (hasActiveChildProcess()) {\n if (schedule) {\n server.rdb_bgsave_scheduled = 1;\n addReplyStatus(c,\"Background saving scheduled\");\n } else {\n addReplyError(c,\n \"Another child process is active (AOF?): can't BGSAVE right now. \"\n \"Use BGSAVE SCHEDULE in order to schedule a BGSAVE whenever \"\n \"possible.\");\n }\n } else if (rdbSaveBackground(server.rdb_filename,rsiptr) == C_OK) {\n addReplyStatus(c,\"Background saving started\");\n } else {\n addReply(c,shared.err);\n }\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" That's why Redis It's single threaded , But it can be generated RDB Provide external services at the same time ."},{"type":"codeinline","content":[{"type":"text","text":"fork"}]},{"type":"text","text":" yes unix Main methods of creating process on system , All data of the parent process will be copied to the child process , Shared memory space between parent and child processes ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"fork after , The operating system kernel sets all memory in the parent process as read-only , Only when a write occurs , Page break will occur , The kernel will copy the corresponding memory page , The parent and child processes each hold one , So it's generating RDB In the process , Due to the use of COW, Dirty memory pages are gradually separated from subprocesses ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Is it possible to call "},{"type":"codeinline","content":[{"type":"text","text":"bgsave"}]},{"type":"text","text":" In the process of , I call again "},{"type":"codeinline","content":[{"type":"text","text":"save"}]},{"type":"text","text":" Orders , Is it not that the time to generate two copies RDB file ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Actually calling "},{"type":"codeinline","content":[{"type":"text","text":"save"}]},{"type":"text","text":" On command ,Redis Will judge "},{"type":"codeinline","content":[{"type":"text","text":"bgsave"}]},{"type":"text","text":" Is execution in progress , If you are executing, the server can no longer call the underlying "},{"type":"codeinline","content":[{"type":"text","text":"rdbsave"}]},{"type":"text","text":" Function , This avoids resource competition between two commands ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" for example , stay "},{"type":"codeinline","content":[{"type":"text","text":"save"}]},{"type":"text","text":" In command , There are the following judgments :"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"if (server.rdb_child_pid != -1) {\n addReplyError(c,\"Background save already in progress\");\n return;\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And in the "},{"type":"codeinline","content":[{"type":"text","text":"bgsave"}]},{"type":"text","text":" There are the following judgments :"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"if (server.rdb_child_pid != -1) {\n addReplyError(c,\"Background save already in progress\");\n} else if (hasActiveChildProcess()) {\n ...\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You can see that they are all judgments of the same variable , as follows :"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"pid_t rdb_child_pid; /* PID of RDB saving child */\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" let me put it another way , Calling save、bgsave When ordered , Will judge ahead of time "},{"type":"codeinline","content":[{"type":"text","text":"bgsave"}]},{"type":"text","text":" Is it still running , If it's running , Will not continue bgsave command . and save The command itself is blocked , If there are other commands coming, they will be blocked , until save completion of enforcement , To deal with it ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Then I will RDB How to use the file after it is generated ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis Called when the server is started "},{"type":"codeinline","content":[{"type":"text","text":"rdbLoad"}]},{"type":"text","text":" function , It will generate RDB The file is loaded into memory , During loading , Every load "},{"type":"text","marks":[{"type":"strong"}],"text":"1000"},{"type":"text","text":" A key will handle a request that has arrived , But only deal with it publish、subscribe、psubscribe、unsubscribe、punsubscribe These five orders . All other requests return errors , Until the load is complete ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You play so well ,RDB What are the advantages and disadvantages of ?"}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" advantage "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB Policies can flexibly configure cycles , It depends on what kind of backup strategy you want . for example :"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Generate the latest every hour 24 Hours of data "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Generate data for the last week every day "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Generate data for the last month every day "}]}]}]},{"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":" Based on this strategy , Can quickly restore the data of a certain period of time before ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" secondly ,RDB It's a great fit "},{"type":"text","marks":[{"type":"strong"}],"text":" Cold backup "},{"type":"text","text":", You can take RDB Files are transferred to other storage media after storage . It can even do "},{"type":"text","marks":[{"type":"strong"}],"text":" Cross cloud storage "},{"type":"text","text":", For example, put OSS At the same time , Put it again S3 On , Cross cloud storage makes data backup more robust ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" and , be based on RDB Recovery rate ratio of mode AOF faster , because AOF It's one by one Redis Instructions ,RDB It's what the data looks like in the end . If there is a large amount of data AOF All instructions "},{"type":"text","marks":[{"type":"strong"}],"text":" replay "},{"type":"text","text":" than RDB More slowly ."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" shortcoming "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"RDB As a "},{"type":"text","marks":[{"type":"strong"}],"text":" Data persistence "},{"type":"text","text":" The scheme is feasible , But if you want to pass RDB Achieve Redis Of "},{"type":"text","marks":[{"type":"strong"}],"text":" High availability "},{"type":"text","text":",RDB It's not so appropriate ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Because if Redis At this time, there is no time to generate the data in memory RDB file , Just hang up , So, since the last successful generation RDB The newly added data will be lost , And I can't get it back ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" and , If there is a large amount of data in memory ,RDB Even through fork Child process , But it also needs to be occupied by the machine "},{"type":"text","marks":[{"type":"strong"}],"text":"CPU resources "},{"type":"text","text":", There may also be a lot of abnormal interruptions , It can also cause the whole thing Redis Stop responding for hundreds of milliseconds ."}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"AOF"}]},{"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":" As mentioned above RDB Can't meet Redis High availability . Because in some cases , Will permanently lose data for a period of time , So let's talk about another solution AOF. First of all, we have to have a concept , That's it RDB Is right for the current Redis Server Data snapshot in , and AOF It is a record of the change order ( All fetch operations are not logged , Because of the current Redis The data didn't change )."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" But that's why ,AOF Documents are better than RDB The file is bigger . Let's talk about one Redis Command request from client to AOF Documentation process ."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"AOF Record the process "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" First Redis Communication is required between the client and the server , The client is not sending the string we wrote , It's specialized "},{"type":"text","marks":[{"type":"strong"}],"text":" Agreement text "},{"type":"text","text":". If you can be familiar with Thrift perhaps Protobuf You should be able to understand this agreement ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" For example, execute command "},{"type":"codeinline","content":[{"type":"text","text":"SET KEY VALUE"}]},{"type":"text","text":", When it reaches the server, it becomes "},{"type":"codeinline","content":[{"type":"text","text":"\"*3\\r\\n$3\\r\\nSET\\r\\n$3\\r\\nKEY\\r\\n$5\\r\\nVALUE\\r\\n\""}]},{"type":"text","text":"."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" then Redis The server will be based on the content of the protocol text , Choose the right handler To deal with . When the client sends instructions to Redis After the server , As long as the command is executed successfully , This command will be propagated to AOF In the program ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Be careful , Spread to AOF The program will not write to disk immediately after the program , Because frequent IO The operation will bring huge cost , It will greatly reduce Redis Performance of , The text of the agreement will be written to Redis In the server aof_buf In the middle , Also called AOF Of "},{"type":"text","marks":[{"type":"strong"}],"text":" Write buffer "},{"type":"text","text":"."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You've written all this to the buffer , When does it land ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" whenever "},{"type":"codeinline","content":[{"type":"text","text":"serverCron"}]},{"type":"text","text":"( First there is one. "},{"type":"text","marks":[{"type":"strong"}],"text":" Timing task "},{"type":"text","text":" The concept of , I'll talk about it in a minute serverCron What is it ) When executed ,"},{"type":"codeinline","content":[{"type":"text","text":"flushAppendOnlyFile"}]},{"type":"text","text":" This function is called ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" This command will call "},{"type":"codeinline","content":[{"type":"text","text":"write"}]},{"type":"text","text":" Writes data written to the buffer to AOF In file , But it's still at this time "},{"type":"text","marks":[{"type":"strong"}],"text":" No, "},{"type":"text","text":" real "},{"type":"text","marks":[{"type":"strong"}],"text":" Drop to disk "},{"type":"text","text":". This is a OS In order to improve the efficiency of writing files , Data will be temporarily written to OS In the buffer , Wait until the buffer is filled or exceeds the specified time , Will call "},{"type":"codeinline","content":[{"type":"text","text":"fsync"}]},{"type":"text","text":" perhaps "},{"type":"codeinline","content":[{"type":"text","text":"sdatasync"}]},{"type":"text","text":" Actually write the contents of the buffer to the disk ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" But if the machine goes down in the meantime , that "},{"type":"text","marks":[{"type":"strong"}],"text":" Data will still be lost "},{"type":"text","text":". So if you want to really AOF The file is saved on disk , You have to call the two functions mentioned above ."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"ServerCron"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" effect "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Now let's talk about it in detail serverCron function , It is mainly used for processing Redis Medium "},{"type":"text","marks":[{"type":"strong"}],"text":" Routine tasks "},{"type":"text","text":"."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" What is a routine task ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" As mentioned above AOF Write buffer , Every time serverCron When it is executed, the AOF write file ( Of course ,OS Will write their own buffer in ). The rest is like AOF and RDB Persistent operation of , Master slave synchronization and cluster related operations , Clean up invalid clients 、 Expiration keys and so on ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" So this one cron How often is it executed ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Many blogs are direct conclusions ,"},{"type":"codeinline","content":[{"type":"text","text":"100ms"}]},{"type":"text","text":" Do it once , Words alone are no proof , We directly copy the source code . Here is serverCron Function definition of ."}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"/* This is our timer interrupt, called server.hz times per second.\n * .............\n */\nint serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {\n ...\n server.hz = server.config_hz;\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In order to avoid affecting people's thinking , I've omitted code and comments that are temporarily useless to us . You can see that there are "},{"type":"codeinline","content":[{"type":"text","text":"called server.hz times per second"}]},{"type":"text","text":". It means serverCron This function will be called in every second. server.hz Time , So this one server.hz What is it ?"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"server.hz"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I'm sure you all know that HZ( Hertz ) This unit , It is the SI unit of frequency , Represents the number of times each periodic event occurs . therefore , We know that this configuration item is used to control the frequency of periodic events ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The assignment is given in the above function , You can see that the initial value is derived from "},{"type":"codeinline","content":[{"type":"text","text":"redis.conf"}]},{"type":"text","text":" Configuration file for . Let's take a look at the configuration ."}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"# Redis calls an internal function to perform many background tasks, like\n# closing connections of clients in timeout, purging expired keys that are\n# never requested, and so forth.\n#\n# Not all tasks are performed with the same frequency, but Redis checks for\n# tasks to perform according to the specified \"hz\" value.\n#\n# By default \"hz\" is set to 10. Raising the value will use more CPU when\n# Redis is idle, but at the same time will make Redis more responsive when\n# there are many keys expiring at the same time, and timeouts may be\n# handled with more precision.\n#\n# The range is between 1 and 500, however a value over 100 is usually not\n# a good idea. Most users should use the default of 10 and raise this up to\n# 100 only in environments where very low latency is required.\nhz 10\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Simply extract useful information ,Redis It will call functions internally to perform many background tasks , And the frequency of calling these functions depends on this "},{"type":"codeinline","content":[{"type":"text","text":"hz"}]},{"type":"text","text":" To decide , The default value is "},{"type":"codeinline","content":[{"type":"text","text":"10"}]},{"type":"text","text":". That means , As mentioned above serverCron The function is executed in one second 10 Time , So, on average, it's per cent 100ms(1000ms/10) Call once ."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Write strategy "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The above said , If Redis Of AOF Already located in OS In the buffer of , If it goes down at this time , that AOF Data will also be lost ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You can't do that , What's the point of persistence ? How can data not be lost ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I need to talk about it AOF Log writing strategy , It has three strategies , They are as follows :"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"always"},{"type":"text","text":" Each command writes a file and synchronizes to disk "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"everysec"},{"type":"text","text":" Synchronize data to disk every second "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"no"},{"type":"text","text":" Do not force writing , wait for OS Decide for yourself when to write "}]}]}]},{"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":" Obviously "},{"type":"codeinline","content":[{"type":"text","text":"always"}]},{"type":"text","text":" This strategy is not desirable in a real production environment , Every command writes a file , It's going to make a huge difference IO expenses , Will occupy Redis Many resources of the server , Reduce Redis Service efficiency of ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And if you use "},{"type":"codeinline","content":[{"type":"text","text":"everysec"}]},{"type":"text","text":" In terms of strategy , Even if there is a power failure , The machine is down , I'll lose a second of data at most ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" and "},{"type":"codeinline","content":[{"type":"text","text":"no"}]},{"type":"text","text":" Then the system will be fully delivered to the operating system for scheduling , More data may be lost ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":", What about this AOF How to use the document , How to recover ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" As mentioned above ,AOF The file records all write commands from the client , So the server just needs to read in and replay it again Redis State recovery for ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" however ,Redis The command can only be executed in the context of the client , therefore Redis A pseudo client with no network connection was created to execute the command , Until the command is executed ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Buddy , You can't do that , In case AOF There is a large amount of log data , Don't you want to recover for a long time , Isn't the service unavailable ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You bet , With the server running ,AOF The amount of data will be larger and larger , Playback will take more and more time . therefore Redis There is one "},{"type":"text","marks":[{"type":"strong"}],"text":" rewrite "},{"type":"text","text":"(AOF Rewrite) Mechanism , To achieve the right AOF Of documents "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":"."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Although the name is right AOF The reduction of documents , But the actual operation to be done is the same as that already generated AOF The document has nothing to do with a dime ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" So-called "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":" By reading Redis The current data status of the server , Of course , This is when the server is running normally . In fact, you can also understand it as a snapshot , It's just not a real binary , It's a command that directly sets the snapshot value ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Let me give you an example , Suppose you Redis There's a key called "},{"type":"codeinline","content":[{"type":"text","text":"test"}]},{"type":"text","text":", The history of its value change is 1 -> 3 -> 5 -> 7 -> 9 such , So if it's normal AOF The file will be recorded 5 strip Redis Instructions . and AOF Rewrite Now step in , Only one will be recorded "},{"type":"codeinline","content":[{"type":"text","text":"test=9"}]},{"type":"text","text":" Data like this ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And before AOF The file is still written as usual , When new AOF Replace the file after it is generated ."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" you tm I'm kidding ? you are here rewrite At the same time , The server is still processing normal requests , At this point, if you change the state of the server , You've been slimming down AOF File data is not consistent ?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" This will happen , however Redis Through one "},{"type":"text","marks":[{"type":"strong"}],"text":"AOF Rewrite buffer "},{"type":"text","text":" To solve this problem ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When "},{"type":"text","marks":[{"type":"strong"}],"text":"rewrite"},{"type":"text","text":" After start ,Redis Meeting fork A subprocess , Let the child process to implement AOF Thin operation of , The parent process can handle the request normally .AOF The override buffer will be in the rewrite Start creating child processes, and then start using , here Redis The server will send the written instructions to two places at the same time :"}]},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"aof_buf, That's what I mentioned above AOF Write buffer for file "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"AOF Rewrite buffer "}]}]}]},{"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":" You may ask , Why do you record in two places ? As mentioned above ,Redis perform "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":" In operation , The conventional AOF The file is still generated normally , So the new Redis The instruction must be sent to the write buffer ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" And sent to AOF The buffer is rewritten to replay the "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":" During the operation, the Redis State changes , such "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":" After that AOF The file status can guarantee the Redis In the same state . in general , Just to make sure "},{"type":"text","marks":[{"type":"strong"}],"text":" Slimming "},{"type":"text","text":" Of AOF Data status in file and Redis The memory state at that time keeps the data consistent ."}]},{"type":"heading","attrs":{"align":null,"level":2}},{"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"}],"text":" Video recommendation :"},{"type":"link","attrs":{"href":"https://www.bilibili.com/video/BV1Wv411B7tX","title":""},"content":[{"type":"text","text":"https://www.bilibili.com/video/BV1Wv411B7tX"}]}]}]}