我可能会问非常基本的问题,但无法通过谷歌搜索找到明确的答案,所以把它放在这里。
Memcached 将信息缓存在一个单独的进程中。因此为了获取缓存的信息需要进程间通信(在java中一般是序列化)。这意味着,通常,要获取缓存对象,我们需要获取序列化对象并将其传输到网络。
序列化和网络通信都是昂贵的操作。如果memcached需要同时使用这两个(一般来说可能有不需要网络通信的情况),那么Memcached有多快呢?复制不是更好的解决方案吗?
或者这是分发/平台独立性/可扩展性与性能的权衡?
我可能会问非常基本的问题,但无法通过谷歌搜索找到明确的答案,所以把它放在这里。
Memcached 将信息缓存在一个单独的进程中。因此为了获取缓存的信息需要进程间通信(在java中一般是序列化)。这意味着,通常,要获取缓存对象,我们需要获取序列化对象并将其传输到网络。
序列化和网络通信都是昂贵的操作。如果memcached需要同时使用这两个(一般来说可能有不需要网络通信的情况),那么Memcached有多快呢?复制不是更好的解决方案吗?
或者这是分发/平台独立性/可扩展性与性能的权衡?
您在考虑中忽略了磁盘 i/o 的成本,这通常是任何进程中最慢的部分,并且是 IMO 使用内存缓存(如 memcached)的主要驱动程序。
您是对的,在共享缓存(如 memcached)中查找某些内容比在本地缓存中查找要慢(我认为您的意思是“复制”)。
但是,共享缓存的优势在于它是共享的,这意味着缓存的每个用户都可以访问比内存用于本地缓存更多的缓存。
考虑一个具有 50 GB 数据库的应用程序,具有十个应用服务器,每个应用程序服务器专用 1 GB 内存用于缓存。如果您使用本地缓存,那么每台机器将有 1 GB 的缓存,等于数据库总大小的 2%。如果您使用共享缓存,那么您有 10 GB 的缓存,等于数据库总大小的 20%。本地缓存的缓存命中率会稍微快一些,但共享缓存的缓存命中率会高得多。由于高速缓存未命中比任何一种高速缓存命中都要昂贵得多,因此命中速度稍慢是为了减少未命中次数而付出的代价。
Now, the exact tradeoff does depend on the exact ratio of the costs of a local hit, a shared hit, and a miss, and also on the distribution of accesses over the database. For example, if all the accesses were to a set of 'hot' records that were under 1 GB in size, then the local caches would give a 100% hit rate, and would be just as good as a shared cache. Less extreme distributions could still tilt the balance.
In practice, the optimum configuration will usually (IMHO!) be to have a small but very fast local cache for the hottest data, then a larger and slower cache for the long tail. You will probably recognise that as the shape of other cache hierarchies: consider the way that processors have small, fast L1 caches for each core, then slower L2/L3 caches shared between all the cores on a single die, then perhaps yet slower off-chip caches shared by all the dies in a system (do any current processors actually use off-chip caches?).
内存缓存通过网络使用 ram 内存。复制使用 ram 内存和持久磁盘内存来获取数据。他们的目的非常不同。
如果您只想使用 Memcached 存储易于获取的数据,例如表记录的 1-1 映射:you-re-gonna-have-a-bad-time:。
另一方面,如果您的数据是复杂 SQL 查询的整个结果集,甚至可能溢出 SQL 内存池(并且需要临时写入磁盘以进行获取),您将看到一个很大的加速.
前面的示例提到需要将数据写入磁盘以进行读取操作 - 是的,如果结果集对于内存来说太大(想象一下CROSS JOIN
),这意味着您既要读取该驱动器又要写入该驱动器(想到颠簸),就会发生这种情况。
例如,在用 C 编写的高度优化的应用程序中,您的总处理时间可能为 1 微秒,并且可能需要等待网络和/或序列化/反序列化(编组/解组)的时间比应用程序执行时间本身要长得多。那时您也会开始感受到网络上的内存缓存的局限性。