Rails caching(Rails高速缓存)

2024-01-19 13:58
文章标签 rails 高速缓存 caching

本文主要是介绍Rails caching(Rails高速缓存),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

 

1. 基本缓存

1.1 page caching

1.2 action caching

1.3 fragment caching

1.4 俄罗斯套娃caching

1.5 共享部分caching

1.6 管理依赖

1.7 低级别caching

1.8 sql caching

2 cache stores

2.1 configuration

2.2 activesupport::cache::store

2.2.1 connection pool options

2.2.2 定义化cache stores

2.3 activesupport::cache::memorystore

2.4 activesupport::cache::filestore

2.5 activesupport::cache::memcachestore

2.6 activesupport::cache::rediscachestore

2.7 activesupport::cache::nuillstore

3. caching in development



本文将介绍如何通过高速缓存机制来加速Rails程序应用。

高速缓存意味着在request-response这个cycle里生成存储数据,然后在反馈相似的请求时复用。

缓存机制是提高应用性能的最高效的机制。通过缓存机制,连接单数据库的单服务器能够支持千级并发。

Rails提供了一系列的开箱即用的caching特性。 本手册将介绍介绍每个特性的范围和目的。

通过阅读本文,你会学到:

  • 片段和俄罗斯套娃缓存
  • 怎么解决缓存依赖
  • 备用缓存存储
  • 条件Get支撑

1. 基本缓存

本段将介绍三种类型的缓存技术: page, action和fragment缓存。默认,Rails提供了片段缓存。为了使用page和action的caching机制,需要在Gemfile中添加actionpack-page_caching和actionpack-action_caching。

默认,caching只在production环境中使用。如果想在本地使用缓存机制,就需要在本地config/environments/*.rb文件中配置config.action_controller.perform_caching=true。这个值的改变仅会影响

Action Controller中的caching,而不会影响到实例中的低级别的caching。

1.1 page caching

page caching允许请求生成一个web page的请求。由于这是特别块的,所以其并不适用于每一个情况,例如认证。这时候的访问就像从一个文件系统直接获取文件,则为了安全期间,我们需要设置cache的失效期。

需要注意的是, page caching已经从Rails 4.0中移除。

1.2 action caching

如上段所说,page caching不能用于filter之前的actions。例如,需要认证的pages,这就是为什么会有action caching。

需要注意的是,action caching也已经从Rails 4.0中移除。

1.3 fragment caching

动态的web应用通常会基于许多组件(存储机制不同)来生成pages。当page中不同部分需要cached,并且需要不同的生命周期时,则需要使用fragment caching。

fragment caching允许view的段落可以被包装成一个cache block然后当下一个请求来的时候从cache store中取出来。

例如,可以用以下代码来cache页面中的每一个product:

<% @products.each do |product| %><% cache product do %><%= render product %><% end %>
<% end %>

当你的应用收到关于这个界面的第一个请求时,Rails会基于唯一键写一个新的cache,例如

views/products/index:bea67108094918eeba42cd4a6e786901/products/1

这个中间的hash字符是基于我们caching的view片段的内容计算出来的。如果这个view片段发生改变,hash字符都会改变,老的cache则会失效,且会从cache stores里删除。

如果想基于某个条件cache某个片段,则可以使用‘cache_if’或者'cache_unless'。

<% cache_if admin?, product do %><%= render product %>
<% end %>

除了单个cache,也可以集合方式cache,如下:

<%= render partial: 'products/product', collection: @products, cached: true %>

1.4 俄罗斯套娃caching

cache也是可以嵌套的,这叫做俄罗斯套娃caching。

俄罗斯套娃caching的优势在于:如果单一产品更新了,其他内嵌的片段可以被重复使用用于生成外部的片段。

当一个cached文件的updated_at变化了,则这个cache就失效了,但是。其内部镶嵌的片段都却不会过期。如下片段:

<% cache product do %><%= render product.games %>
<% end %>

当game的任一属性改变了,则updated_at会设置成当前时间,然后game的cache会过期。然而,相关联的product会不会因此而过期,从而产生陈旧数据,这是不正确的。

则为了解决这个问题, 我们需要用touch方法将这两个主题连接起来。

class Product < ApplicationRecordhas_many :games
endclass Game < ApplicationRecordbelongs_to :product, touch: true
end

这样的话,任何game的变化都会引起相关联的product的cache的更新。

1.5 共享部分caching

共享部分cachings也是有可能实现的。例如,共享部分caching允许模版在html和javascripts文件件共享部分文件。

1.6 管理依赖

为了正确的废止cache,我们需要正确定义caching依赖。Rails默认能处理一般例子,然而,有时,当你处理定制化的helpers时,则需要显示定义他们。

隐式依赖定义:

 

render @project.documents.where(published: true)

 

显示依赖定义:

<%# Template Collection: notification %>
<% my_helper_that_calls_cache(some_arg, notification) do %><%= notification.name %>
<% end %>

 

1.7 低级别caching

有时,我们不需要去cocah view的片段,而仅仅需cache一个值或者query的结果。幸运的是,rails的caching机制支持保存任何信息。

最高效的实现底层caching则需要用rails.cache.fetch方法。这个方法支持读写cache。当参数是一个值时,则key被获取,caches里的值被返回。如果参数是一个块,则没有cache时,该代码块会被执行,然后返回值会被写进cache。

如下例子:

class Product < ApplicationRecorddef competing_priceRails.cache.fetch("#{cache_key_with_version}/competing_price", expires_in: 12.hours) doCompetitor::API.find_price(id)endend
end

1.8 sql caching

query caching缓存每一个query返回的查找结果。如果rails遇到相同的query,则会使用cached的值,而不会再次查询。

例如:

class ProductsController < ApplicationControllerdef index# Run a find query@products = Product.all...# Run the same query again@products = Product.allendend

这二次去数据库执行相同的查询,但是并不是去真正的访问数据库。第一次查询返回的结果存储在query cache里面(内存里),第二次会直接从内存中获取到。

然而,查询caches在一个action开始的时候创建,在action结束的时候销毁,所以仅仅存在在一个action的生命周期里。如果你希望这个查询结果保存的更长久,则可以使用low-level caching。

2 cache stores

除了sql和page caching,rails为不同的存储数据存储了不同的存储。

2.1 configuration

你可以通过设置config.cache_store配置选项来配置应用程序默认的cache store。如下:

config.cache_store = :memory_store, { size: 64.megabytes }

除了这种方法,你还可以在configuration块外调用actioncontroller::base.cache_store去定义cache store.

还可以通过rails cache去获取cache。

2.2 activesupport::cache::store

这个类提供了rails中cache交互基础。这个是抽象类,我们不能直接使用。我们在具体化类时需要和存储引擎绑定。

主要方法包括:read, write, delete, exist?和 fetch。

2.2.1 connection pool options

默认的,MemCacheStore和RedisCacheStore使用一个单一的连接进程。如果想增加可用连接的数字,则使能connection pooling。

第一步,在Gemfile文件中添加connection_pool 

gem 'connection_pool'

然后,在配置cache store时陪你pool_size和pool_timeout,如下:

config.cache_store = :mem_cache_store, "cache.example.com", { pool_size: 5, pool_timeout: 5 }

2.2.2 定义化cache stores

我们可以通过继承activesupport::cache::store来创建自己的cache store。如下实例化类:

config.cache_store = MyCacheStore.new

2.3 activesupport::cache::memorystore

这个cache stor保存在同一进程中的实例在内存中。我们可以通过以下配置类初始化cache store。默认大小为32m,当所占的内存超过该值时,则使用最少的一些值会被清除。

config.cache_store = :memory_store, { size: 64.megabytes }

如果rails应用多程序运行譬如用了phusion passenger,则rails server process实例间无法共享cache 数据。这种cache store对大型应用的部署并不适用。而对于small, low traffic的网站,却能很好的适用。

由于当我们使用:memory_store,进程间无法共享进程,所以我们无法通过rails console去手动的读写或者失效cache。

2.4 activesupport::cache::filestore

这种cache store用文件系统去存储实体。如下:

config.cache_store = :file_store, "/path/to/cache/directory"

如果我们没有如上设定位置,则cache默认会存储在“#{root}/tmp/cache”目录下

2.5 activesupport::cache::memcachestore

这个cache store用danga's memcached 服务器为服务提供了中心化的缓存。rails默认用了dundled dalli gem。这是目前对production网站最流行的cache store。他可以用来提供单一的,共享的高性能高冗余的cache集群。

当初始化cache时,你需要指定集群中memcached servers的地址,如下:

config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"

如果不指定地址,则默认为本地(如下),对于小网站,这样是可以的,但是对于大型应用是不可以的。、

config.cache_store = :mem_cache_store # Will fallback to $MEMCACHE_SERVERS, then 127.0.0.1:11211

2.6 activesupport::cache::rediscachestore

redis cache store的优势是当达到最大存储空间会自动清理。我们需要在gemfile中添加redis gem。如下:

gem 'redis'

我们可以使能更快的hiredis链接库。我们需要在gemfile中添加hiredis gem。如下:

gem 'hiredis'

redis cache store会自动需要和使用hiredis。而不需要其他更多额外的配置。

2.7 activesupport::cache::nuillstore

这个cache store的实现意味着其仅在development和test环境中使用,且不存储任何东西。这在开发时是很有用的,你可以通过rails.cache直接看到代码的变化。

config.cache_store = :null_store

3. caching in development

我们说了通常cache只在production环境中有效,当我们想在开发环境中测试我们的cache机制时,rails提供了dev:cache去方便的打开和关闭caching。如下:

$ bin/rails dev:cache
Development mode is now being cached.
$ bin/rails dev:cache
Development mode is no longer being cached.

 

这篇关于Rails caching(Rails高速缓存)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/622640

相关文章

【异常】java.sql.SQLException: Unable to load authentication plugin ‘caching_sha2_password‘.

异常现象 执行mysql数据库操作的时候,出现以下异常信息: java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:868) ~[mysql-connector-

rails 5的actioncable在某些环境下wss协议被阻止的问题

在调试redmine的一个websocket插件时,在cloud studio环境上遇到action cable的request失败问题,搜google之后,可以通过如下改动解决,在enviroments/development.rb里,做一些设置适配: https://stackoverflow.com/questions/35188892/request-origin-not-allowed-

Ruby on Rails 开发 web

Ruby on Rails 正在令整个 Web 开发领域受到震憾。让我们首先了解底层的技术: Ruby 是一门免费的、简单的、直观的、可扩展的、可移植的、解释的脚本语言,用于快速而简单的面向对象编程。类似于 Perl,它支持 处理文本文件和执行系统管理任务的很多特性。 Rails 是用 Ruby 编写的一款完整的、开放源代码的 Web 框架,目的是使用更简单而且更少的代码编写实际使用的应

利用Redis高速缓存实现Tomcat集群在Nginx负载均衡机制下的Session共享

为什么要共享session? 我们使用单台Tomcat的时候不会有共享sesssion的疑虑,只要使用Tomcat的默认配置即可,session即可存储在Tomcat 但是随着业务的扩大,增加Tomcat节点构成Tomcat集群大势所趋,分布式带来了增加更大规模并发请求的优势,但是也随之到来了一个问题,每个Tomcat只存储来访问自己的请求产生的session,如果Tomcat-A已经为客

MySQL8.0 以上版本 “caching_sha2_password cannot be loaded” 问题解决办法

MySQL8 以上版本客户端登录 “caching_sha2_password cannot be loaded” 问题 解决办法1: 用root用户登录mysql,然后执行两行命令: ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '密码';FLUSH PRIVILEGES; 注: 1. docker部署的M

mysql:2059 -Authentication plugin ‘caching-sha2-password‘解决办法

出现 “Authentication plugin ‘caching_sha2_password’ cannot be loaded” 错误通常意味着 MySQL 客户端和服务器之间在尝试使用 caching_sha2_password 认证插件时遇到了问题。以下是一些可能的解决步骤: 亲测有效 更改用户身份验证方式:可以尝试将用户的身份验证方式更改为较旧的插件,你可以在 MySQL 中执行以下

在做RAG以前你可以尝试的事:Prompt Caching

近年来,科技领域的创新不断涌现,为我们带来了许多令人兴奋的技术突破和应用。近期,Anthropic公司引入了与Claude配合使用的提示缓存技术(prompt caching),这项技术能够将长提示的成本降低高达90%,延迟减少高达85%。这一技术有望成为小规模检索增强生成(RAG)的一个良好替代方案。然而,实际上谷歌才是最早通过其API引入上下文缓存(context caching)技术的公

rails中Can't verify CSRF token authenticity错误解决办法

在rails中 以客户端去访问服务器端 经常会终端出现 Can't verify CSRF token authenticity   这是由于客户端访问服务器端   rails会需要token验证 只需要在服务端对应的Controller中加入 skip_before_filter :verify_authenticity_token,:only => : funct

rails 中i18n实现本地化

在rails中写东西时,因为默认语言是英文的,所以很多已有的提示都是英语,而这对于一个中文网站来说并不友好. 所以一般会使用i18n来实现本地化 在application.rb文件中 写入 config.i18n.default_locale = 'zh_CN' 然后在config/locales文件下 创建 zh_CN.yml文件  内容格式如下: zh

rails中will_paginate插件,当前页的使用

在will_paginate中current_page是一个private 但是 如果想使用当前也的话,直接用params[:page]就可以了 在redirect_to时  记得传递(:page=>params[:page]) 使用它 可以完成  分页后的排列编号, 分页后返回原页等功能了 但是这里还有一个漏洞, 就是如果当前页用户已经为空了, 页面依然会显示在这个空页上