当前位置:网站首页>[high concurrency] how does readwritelock relate to caching?!

[high concurrency] how does readwritelock relate to caching?!

2021-01-23 22:12:00 InfoQ

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Write it at the front ","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":" In practice , There is a very common concurrency scenario : That's the scene of reading more and writing less . In this case , To optimize the performance of the program , We often use caching to improve the access performance of applications . Because cache is very suitable for use in the scene of more read and less write . And in a concurrent scenario ,Java SDK Provided in ReadWriteLock To satisfy the situation of reading more and writing less . Let's talk about the use of ReadWriteLock How to implement a general cache Center .","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 knowledge points involved in this paper are :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/78/7846332ad933dde2c16dd3fc97baf928.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},"content":[{"type":"text","text":" The article has been included 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":"link","attrs":{"href":"https://github.com/sunshinelyz/technology-binghe","title":""},"content":[{"type":"text","text":"https://github.com/sunshinelyz/technology-binghe","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":"link","attrs":{"href":"https://gitee.com/binghe001/technology-binghe","title":""},"content":[{"type":"text","text":"https://gitee.com/binghe001/technology-binghe","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Read-write lock ","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":" Talking about read write lock , I believe my friends are not strange . On the whole , Read write locks need to follow the following principles :","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":" A shared variable can be read by multiple read threads at the same time .","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" A shared variable can only be written by one write thread at a time .","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When a shared variable is written by a written thread , At this time, the shared variable cannot be read by the read thread .","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","marks":[{"type":"strong","attrs":{}}],"text":" here , What we need to pay attention to is : An important difference between read-write locks and mutexes is : Read write locks allow multiple threads to read shared variables simultaneously , Mutex does not allow . therefore , In high concurrency scenarios , Read write locks perform better than mutexes . however , The read and write lock is mutually exclusive , in other words , When using a read-write lock , When a shared variable is written by a written thread , At this time, the shared variable cannot be read by the read thread .","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":" Read write locks support fair mode and unfair mode , Specifically in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ReentrantReadWriteLock","attrs":{}}],"attrs":{}},{"type":"text","text":" Pass a boolean Type of variable to control .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public ReentrantReadWriteLock(boolean fair) {\n sync = fair ? new FairSync() : new NonfairSync();\n readerLock = new ReadLock(this);\n writerLock = new WriteLock(this);\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","marks":[{"type":"strong","attrs":{}}],"text":" in addition , One thing to note is that : In the read-write lock , Read lock call newCondition() Will throw out UnsupportedOperationException abnormal , in other words : Read lock does not support conditional variables .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Cache implementation ","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":" here , We use ReadWriteLock Quickly implement a general tool class for caching , The overall code is as follows .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public class ReadWriteLockCache {\n private final Map m = new HashMap<>();\n private final ReadWriteLock rwl = new ReentrantReadWriteLock();\n // Read the lock \n private final Lock r = rwl.readLock();\n // Write lock \n private final Lock w = rwl.writeLock();\n // Read cache \n public V get(K key) {\n r.lock();\n try { return m.get(key); }\n finally { r.unlock(); }\n }\n // Write cache \n public V put(K key, V value) {\n w.lock();\n try { return m.put(key, value); }\n finally { w.unlock(); }\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":" You can see , stay ReadWriteLockCache in , We define two generic types ,K For cache Key,V For cache value. stay ReadWriteLockCache Class internal , We use Map To cache the corresponding data , Everyone knows HashMap It's not thread safe , therefore , Read and write locks are used here to ensure thread security , for example , We are get() Read lock is used in the method ,get() Methods can be read by multiple threads at the same time ;put() Method uses a write lock internally , in other words ,put() Method only one thread can write to the cache at the same time .","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":"** What needs to be noted here is : Whether it's a read lock or a write lock , All lock release operations need to be placed in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"finally{}","attrs":{}}],"attrs":{}},{"type":"text","text":" Block of code .**","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":" In the past experience , There are two ways to load data into the cache ,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" One is : When the project starts , Load the full amount of data into the cache , One is during the running of the project , Load the required cache data on demand .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5a/5a31e446e774c3ade3786725ba2d89d8.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},"content":[{"type":"text","text":" Next , Let's take a look at the full load cache and the on-demand load cache respectively .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Full load cache ","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":" It's relatively easy to load a full cache , At the start of the project , Load data into the cache at one time , This applies to a small amount of cached data , A scenario where data changes infrequently , for example : You can cache some data dictionaries and other information in the system . The whole process of cache loading is as follows .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/74/74cbc37c003e21557329e3e03121363d.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},"content":[{"type":"text","text":" After loading the full amount of data into the cache , Then you can read the corresponding data directly from the cache .","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 code implementation of full load cache is relatively simple , here , I'll just use the following code to demonstrate .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public class ReadWriteLockCache {\n private final Map m = new HashMap<>();\n private final ReadWriteLock rwl = new ReentrantReadWriteLock();\n // Read the lock \n private final Lock r = rwl.readLock();\n // Write lock \n private final Lock w = rwl.writeLock();\n \n public ReadWriteLockCache(){\n // Query the database \n List> list = .....;\n if(!CollectionUtils.isEmpty(list)){\n list.parallelStream().forEach((f) ->{\n\t\t\t\tm.put(f.getK(), f.getV);\n\t\t\t});\n }\n }\n // Read cache \n public V get(K key) {\n r.lock();\n try { return m.get(key); }\n finally { r.unlock(); }\n }\n // Write cache \n public V put(K key, V value) {\n w.lock();\n try { return m.put(key, value); }\n finally { w.unlock(); }\n }\n}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Load the cache on demand ","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":" On demand caching can also be called lazy loading , That is to say : The data will be loaded into the cache only when it needs to be loaded . say concretely : It's when the program starts , No data will be loaded into the cache , When running , You need to query some data , First, check whether there is the required data in the cache , If there is , Then read the data in the cache directly , If it doesn't exist , Query the data in the database , And write the data to the cache . Subsequent read operations , Because the corresponding data already exists in the cache , Return the cached data directly .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ae/aeb1d41907547f889eb0dba4dbe95d7e.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},"content":[{"type":"text","text":" This query caching method is suitable for most scenarios where data is cached .","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 can use the following code to represent the business of on-demand query caching .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"class ReadWriteLockCache {\n private final Map m = new HashMap<>();\n private final ReadWriteLock rwl = new ReentrantReadWriteLock();\n private final Lock r = rwl.readLock();\n private final Lock w = rwl.writeLock();\n V get(K key) {\n V v = null;\n // Read cache \n r.lock(); \n try {\n v = m.get(key);\n } finally{\n r.unlock(); \n }\n // There is... In the cache , return \n if(v != null) { \n return v;\n } \n // There is no... In the cache , Query the database \n w.lock(); \n try {\n\t\t // Verify again that there is data in the cache \n v = m.get(key);\n if(v == null){ \n // Query the database \n v= Data from the database \n m.put(key, v);\n }\n } finally{\n w.unlock();\n }\n return v; \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":" here , stay get() In the method , First, read the data from the cache , here , We add a read lock to the query cache operation , After the query returns , To unlock . Determine whether the data returned in the cache is empty , Not empty , Then directly return the data ; If it is empty , Get the write lock , Then read the data from the cache again , If there is no data in the cache , Then query the database , Write the result data to the cache , Release the write lock . Finally, the result data 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":"text","marks":[{"type":"strong","attrs":{}}],"text":" here , A partner may ask : Why has the program added a write lock , Why query the cache once inside the write lock ?","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":" This is because in a high concurrency scenario , There may be multiple threads competing for write locks . for example : First execution get() When the method is used , The data in the cache is empty . If there are three threads calling at the same time get() Method , Run to... At the same time ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"w.lock()","attrs":{}}],"attrs":{}},{"type":"text","text":" Code office , Because of the exclusivity of write locks . At this point, only one thread will get the write lock , The other two threads are blocked in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"w.lock()","attrs":{}}],"attrs":{}},{"type":"text","text":" It's about . The thread that gets the write lock continues to query the database , Write data to cache , Then release the write lock .","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":" here , Two other threads compete to write locks , A thread will get the lock , So let's keep going , If in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"w.lock()","attrs":{}}],"attrs":{}},{"type":"text","text":" There is no ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" v = m.get(key);","attrs":{}}],"attrs":{}},{"type":"text","text":" Query the cached data again , The thread will query the database directly , Release the write lock after writing data to the cache . The last thread will also follow this 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":" here , In fact, the first thread has already queried the database , And write the data to the cache , There is no need for the other two threads to query the database again , Directly query the corresponding data from the cache . therefore , stay ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"w.lock()","attrs":{}}],"attrs":{}},{"type":"text","text":" Add ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" v = m.get(key);","attrs":{}}],"attrs":{}},{"type":"text","text":" Query the cached data again , It can effectively reduce the problem of repeatedly querying the database in high concurrency scenarios , Improve the performance of the system .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" The level of the read-write lock ","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":" About the lifting level of the lock , What you guys need to pay attention to is : stay ReadWriteLock in , Locks do not support upgrade , Because before the read lock is released , At this point, get the write lock , Will cause the write lock to wait forever , The corresponding thread will also be blocked and unable to wake up .","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":" Although lock upgrade is not supported , however ReadWriteLock Support lock degradation , for example , Let's take a look at the official ReentrantReadWriteLock Example , As shown below .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"class CachedData {\n Object data;\n volatile boolean cacheValid;\n final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();\n\n void processCachedData() {\n rwl.readLock().lock();\n if (!cacheValid) {\n // Must release read lock before acquiring write lock\n rwl.readLock().unlock();\n rwl.writeLock().lock();\n try {\n // Recheck state because another thread might have\n // acquired write lock and changed state before we did.\n if (!cacheValid) {\n data = ...\n cacheValid = true;\n }\n // Downgrade by acquiring read lock before releasing write lock\n rwl.readLock().lock();\n } finally {\n rwl.writeLock().unlock(); // Unlock write, still hold read\n }\n }\n\n try {\n use(data);\n } finally {\n rwl.readLock().unlock();\n }\n }\n}}","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Data synchronization issues ","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":" First , Data synchronization here refers to data synchronization between data source and data cache , More directly , Data synchronization between database and cache .","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":" here , We can take three solutions to solve the problem of data synchronization , As shown in the figure below ","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a7/a7106a8f32b7d45eb645b0bc503b2ba4.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":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Timeout mechanism ","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":" This is easier to understand , When writing data to the cache , Give me a timeout , When the cache times out , The cached data is automatically removed from the cache , When the program accesses the cache again , Because there is no corresponding data in the cache , Query the database to get the data , Then write the data to the cache .","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":" In this way, we need to pay attention to the problem of cache penetration , About cache penetration 、 breakdown 、 Knowledge of avalanches , You guys can see 《","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?_biz=Mzg4MjU0OTM1OA==&mid=2247489193&idx=1&sn=6d8912a62f5fd09c85a3d44a189e7ef9&chksm=cf55a1a8f82228be7c76699df36377e57347249e1d15b48bad9ef15f2497e9254a36b8d24bad&token=456594555&lang=zhCN#rd","title":""},"content":[{"type":"text","text":"【 High concurrency 】 interviewer : Talk about cache penetration ? breakdown ? An avalanche ? How to solve ?","attrs":{}}]},{"type":"text","text":"》","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Update the cache regularly ","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":" This scheme is an enhanced version of the timeout mechanism , When writing data to the cache , Also give a timeout . Unlike the timeout mechanism , Start a single thread in the background of the program , Query the data in the database regularly , The data is then written to the cache , This can avoid cache penetration to a certain extent .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" Update cache in real time ","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":" This scheme can achieve real-time synchronization between the data in the database and the cached data , You can use Alibaba open source Canal Framework implementations MySQL Real time synchronization between database and cache data .","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" You can also use my own open source mykit-data Frame ( Recommended )~~","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Recommended reading ","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":"link","attrs":{"href":"https://mp.weixin.qq.com/s?_biz=Mzg4MjU0OTM1OA==&mid=2247489193&idx=1&sn=6d8912a62f5fd09c85a3d44a189e7ef9&chksm=cf55a1a8f82228be7c76699df36377e57347249e1d15b48bad9ef15f2497e9254a36b8d24bad&token=456594555&lang=zhCN#rd","title":""},"content":[{"type":"text","text":"【 High concurrency 】 interviewer : Talk about cache penetration ? breakdown ? An avalanche ? How to solve ?","attrs":{}}]}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?_biz=Mzg4MjU0OTM1OA==&mid=2247490278&idx=1&sn=1681ff3ce2d7ccc133d5a4436fb21359&chksm=cf55ade7f82224f145462689ed0b0e7d0e86e162c1707a954b30fcb293f997d60568f2466534&token=456594555&lang=zhCN#rd","title":""},"content":[{"type":"text","text":" Two lines of code fix parsing MySQL8.x binlog The problem of dislocation !!","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":"mykit-data Open source address :","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":"link","attrs":{"href":"https://github.com/sunshinelyz/mykit-data","title":""},"content":[{"type":"text","text":"https://github.com/sunshinelyz/mykit-data","attrs":{}}]},{"type":"text","text":" ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://gitee.com/binghe001/mykit-data","title":""},"content":[{"type":"text","text":"https://gitee.com/binghe001/mykit-data","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","marks":[{"type":"strong","attrs":{}}],"text":" Okay , That's all for today , I'm glacier , If you have any questions, please leave a message below , I can also add wechat :sun_shine_lyz, I'll pull you into the group , Exchange technology together , Step up together , Let's fight together ~~","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/01/20210123221032361T.html

随机推荐