I have this problem related to maintaining and I have looked in several places for the answer but I have found no specific answer.
我有这个问题与维护有关,我已经在几个地方寻找答案,但我没有找到具体的答案。
The situation is like this:
情况是这样的:
We have several mysql queries which generate menus for our web application. About once a day, we need to update the tables and those updates affect the menu generation. Naturally, we enclose those updates within a transaction.
我们有几个mysql查询,它们为我们的Web应用程序生成菜单。大约每天一次,我们需要更新表格,这些更新会影响菜单生成。当然,我们将这些更新包含在事务中。
So far so good. But the improve the speed and responsiveness and also reduce database load, we want to use memcached. And in all respects, memcached is perfect for this role because the updates happen only once a day.
到现在为止还挺好。但是提高速度和响应能力以及减少数据库负载,我们要使用memcached。在各方面,memcached都非常适合这个角色,因为更新每天只发生一次。
But what we would like to do is this:
但我们想做的是:
-
Our update scripts starts and its first operation is to "suspend" the memcached pool. Once this is done, memcached no longer answers queries and all queries are passed through to mysql. The important thing is that the memcached server still responds with a miss quickly so that mysql comes into action quickly. The other important thing is that during this period, memcached will refuse to set any data.
我们的更新脚本启动,其第一个操作是“暂停”memcached池。完成后,memcached不再回答查询,所有查询都会传递给mysql。重要的是memcached服务器仍然快速响应,以便mysql快速生效。另一个重要的事情是,在此期间,memcached将拒绝设置任何数据。
-
Flush all data in memcached pool.
刷新memcached池中的所有数据。
-
Update script runs.
更新脚本运行。
-
Restore memcached to normal operation.
将memcached恢复到正常运行状态。
So, 1. and 4. is where I am stuck.
所以,1。和4.是我被困的地方。
Our technology is based around mysql and PHP. I am using the nginx memcached module to directly retrieve data from memcached. But the PHP which sets the cache could run in many different places.
我们的技术基于mysql和PHP。我正在使用nginx memcached模块直接从memcached中检索数据。但是设置缓存的PHP可以在许多不同的地方运行。
Having said that, I am open to using any language or technology. This is a generic enough problem and we could discuss anything that works best.
话虽如此,我愿意使用任何语言或技术。这是一个通用的问题,我们可以讨论最有效的方法。
Thanks in advance for responses.
在此先感谢您的回复。
2 个解决方案
#1
The usual method of (atomically) swapping over from one set of data in cache is with a Namespace
. A prefix that is stored in its own key and is queried first before going on to fetch the main cached data.
从缓存中的一组数据(原子)交换的常用方法是使用命名空间。存储在其自己的密钥中的前缀,在继续获取主缓存数据之前首先进行查询。
It works like this:
它的工作原理如下:
- You have a 'namespace' under a key - it could be date/time based for example -
menuNamespace = 'menu:15050414:'
(the 2015-05-04, 2pm menu build). - That key is a prefix for all the actual data for the menus, or other data, eg:
menu:15050414:top-menu
,menu:15050414:l2-menu
, etc, etc - The back end system builds a new set of cached data with new keys:
menu:15050510:top-menu
,menu:15050510:l2-menu
- Only when the data is in place, do you change namespace key cached entry from 'menu:15050414:' to 'menu:15050510:'
- The next time the namespace is fetched, it is used as a prefix to then fetch the new data.
您在键下有一个“命名空间” - 例如,它可以是基于日期/时间 - menuNamespace ='menu:15050414:'(2015-05-04,下午2pm菜单构建)。
该键是菜单或其他数据的所有实际数据的前缀,例如:menu:15050414:top-menu,menu:15050414:l2-menu等等
后端系统使用新密钥构建一组新的缓存数据:menu:15050510:top-menu,menu:15050510:l2-menu
只有在数据到位时,您是否将名称空间密钥缓存条目从'menu:15050414:'更改为'menu:15050510:'
下次提取命名空间时,它将用作前缀,然后获取新数据。
There is some more in a MemcacheD FAQ/tricks page on Namespacing.
Namespacing上的MemcacheD FAQ / tricks页面还有更多内容。
#2
Based on @alister_b's initial answer, there is a simpler way to solve my initial problem.
基于@ alister_b的初始答案,有一种更简单的方法可以解决我的初始问题。
The key is to signal to the PHP code to stop setting the cache values. That can be done through memcached entry like setCache:false or through a MySQL column.
关键是向PHP代码发出信号以停止设置缓存值。这可以通过像setCache:false这样的memcached条目或通过MySQL列来完成。
Then, a flush command will guarantee nginx cache misses.
然后,flush命令将保证nginx缓存未命中。
Once the tables are updated, setCache is set to true and normal sets by php are resumed.
更新表后,将setCache设置为true,并恢复php的正常设置。
This will work with my Ajax calls without issues.
这将适用于我的Ajax调用没有问题。
It is not mutually exclusive with namespaces.
它与名称空间不是互斥的。
#1
The usual method of (atomically) swapping over from one set of data in cache is with a Namespace
. A prefix that is stored in its own key and is queried first before going on to fetch the main cached data.
从缓存中的一组数据(原子)交换的常用方法是使用命名空间。存储在其自己的密钥中的前缀,在继续获取主缓存数据之前首先进行查询。
It works like this:
它的工作原理如下:
- You have a 'namespace' under a key - it could be date/time based for example -
menuNamespace = 'menu:15050414:'
(the 2015-05-04, 2pm menu build). - That key is a prefix for all the actual data for the menus, or other data, eg:
menu:15050414:top-menu
,menu:15050414:l2-menu
, etc, etc - The back end system builds a new set of cached data with new keys:
menu:15050510:top-menu
,menu:15050510:l2-menu
- Only when the data is in place, do you change namespace key cached entry from 'menu:15050414:' to 'menu:15050510:'
- The next time the namespace is fetched, it is used as a prefix to then fetch the new data.
您在键下有一个“命名空间” - 例如,它可以是基于日期/时间 - menuNamespace ='menu:15050414:'(2015-05-04,下午2pm菜单构建)。
该键是菜单或其他数据的所有实际数据的前缀,例如:menu:15050414:top-menu,menu:15050414:l2-menu等等
后端系统使用新密钥构建一组新的缓存数据:menu:15050510:top-menu,menu:15050510:l2-menu
只有在数据到位时,您是否将名称空间密钥缓存条目从'menu:15050414:'更改为'menu:15050510:'
下次提取命名空间时,它将用作前缀,然后获取新数据。
There is some more in a MemcacheD FAQ/tricks page on Namespacing.
Namespacing上的MemcacheD FAQ / tricks页面还有更多内容。
#2
Based on @alister_b's initial answer, there is a simpler way to solve my initial problem.
基于@ alister_b的初始答案,有一种更简单的方法可以解决我的初始问题。
The key is to signal to the PHP code to stop setting the cache values. That can be done through memcached entry like setCache:false or through a MySQL column.
关键是向PHP代码发出信号以停止设置缓存值。这可以通过像setCache:false这样的memcached条目或通过MySQL列来完成。
Then, a flush command will guarantee nginx cache misses.
然后,flush命令将保证nginx缓存未命中。
Once the tables are updated, setCache is set to true and normal sets by php are resumed.
更新表后,将setCache设置为true,并恢复php的正常设置。
This will work with my Ajax calls without issues.
这将适用于我的Ajax调用没有问题。
It is not mutually exclusive with namespaces.
它与名称空间不是互斥的。