启动船上的Redis用轨道
#redis #rails #upstash

介绍

您是否曾经想过是否有一个开源数据库具有快速响应时间和键值存储基础?

答案是肯定的。引入 redis ,一个开源数据库,内存,键值数据存储,开发人员经营五年来一直是most-loved databaseRedis通常用作主要数据库,缓存,队列和消息代理。 REDIS是一个开源(BSD许可),主要用作应用程序缓存和快速响应数据库,并且因为数据存储在内存中而不是存储在磁盘中,因此Redis提供了无与伦比的速度,可靠性和性能。

>

redis提供数据结构,例如字符串,哈希,列表,集合,排序集,位图,流等等。有关Redis data types的更多信息。为了达到最佳性能,REDIS可以通过定期将数据集转移到磁盘或将每个命令附加到基于磁盘的日志中来持久数据。 redis用 ansi c 编写,并在Linux等大多数POSIX系统和无外部依赖性的Mac OS X上工作。 Redis几乎可以在每种编程语言中使用。您可以找到Redis Clients页。

升级

Upstash是一个云数据库提供商,拥有超过3.5万用户(每个日期),总数超过4.8万个数据库活动。包括Redis,Kafka和QStash在内的Upstash产品提供了免费计划,其中包括最多10,000个命令,TLS加密和持久存储,非常适合希望在不收费的情况下尝试其产品的开发人员。我认为最好的是定价。 付费,这意味着我们只为我们使用的价格使用的价格付费。即使您升级到付费计划,您也只需支付每100k命令的0.2美元(区域)(有关Upstash Redis Pricing的更多信息)。

在这篇文章中,我将为您提供有关如何用途Upstash Redis的入门指南,以后我们将其与Ruby在Rails应用程序上集成。

Upstash控制台

在开始使用UpStash Redis之前,您要做的第一件事就是在Upstash中创建一个帐户。转到https://console.upstash.com/login并创建一个帐户。然后,您可以登录到Upstash Console。您会看到类似此页面的内容

Upstash Console

通过单击创建数据库按钮开始创建数据库,您将看到模态并填写表单。对于类型,选择区域,然后选择最接近应用程序的区域,以便您可以以低延迟访问数据库。

Upstash Create Database

您将被重定向到数据库详细信息

Upstash Database Details

您可以在此页面上使用一些功能:

  • 详细信息:在本节中,您可以看到数据库的详细信息,例如区域,端点,密码,端口和TLS/SSL状态。
  • 用法:您可以看到请求总数,今天的带宽,每日请求和总成本。
  • cli:这正是Redis CLI,但在浏览器中,尝试键入ping。如果成功,您将获得响应PONG
  • 数据浏览器:您可以查看您在此页面上数据库中存储的数据。
  • 备份:您可以在此页面上配置备份配置。 UpStash只会保留最新的备份并覆盖上一个。此功能只能为付费用户启用。
  • Quickstarts:如果您不知道如何开始使用Upstash Redis,那么这是一个好地方之一。您可以看到如何在某些框架或边缘功能中开始。

REDIS API兼容性

开始在应用程序中安装REDIS客户端之前,首先我们需要了解Upstash中的Redis API兼容性。当前,UpStash支持REDIS客户协议至6.2版。下表显示了支持的redis命令的列表:

功能 支持? 支持的命令
String 附录 - dect -decrby -get -getdel -getEx -getRange -getSet -getSet- getse- corm-crecby-crecbyfloat- mget- mget -metnx -msetnx -msetnx -psetex -psetex -setex -set -set -setex -setnx -setnx -setrange -strlange -strlange -strlange -strlange
Bitmap bitcount -bitfield -bitfield_ro -bitop -bitpos -getbit -setbit
Hash hdel-六角主义者 - hget -hgetall -hincrby -hincrbyfloat -hkeys -hlen -hlen -hmget -hmte -hmset -hmset -hscan -hscan -hset -hsetnx -hsstrlen -hrandfield -hrandfield -hrandfield -hvals -hvals -hvals -hvals
List BLMOVE - BLPOP - BRPOP - BRPOPPLPUSH - Lindex - Lentil - LLEN - LMOVE - LPOP - LPOS - LPUSH - LPUSHX - LRANGE - LREM - LST - LTRIM - RPOP - RPOPLPUSH - RPUSH - RPUSHX
Set 萨德 - scard -sdiff -sdiffstore-烧结 - 辛特店 - sismember -smembers -smimbers -smismember -smimember -smove -spop -srandmember -srandmember -srem -sscan -sscan -sscan -sunion -sunionstore -sunionstore
SortedSet BZPOPMAX - BZPOPMIN - ZADD - ZCARD - ZCOUNT - ZDIFF - ZDIFFSTORE - ZINCRBY - ZINTER - ZINTERSTORE - ZLEXCOUNT - ZMSCORE - ZPOPMAX - ZPOPMIN - ZRANDMEMBER - ZRANGE - ZRANGESTORE - ZRANGEBYLEX - ZRANGEBYSCORE - ZRANK - ZREM - ZREMRANGEBYLEX - ZREMRANGEBYRANK - ZREMRANGEBYSCORE -Revignge -RevRangeBylex -RevrangeBysCore -Revrank -ZSCAN -ZSCORE -ZUNION -ZUNIONSTORE
Transactions 丢弃 - exec-多 - untch-观看
Generic 复制 - del-存在 - 有效 - expireat -键 - 键 - pexpire -pexpireat -pexpireat -pttl -randykeke- rename -rename -renamenx- scan -scan -touch -ttl- ttl -type -unlink
Connection auth- auth- Hello -Echo -Ping -Quit -Reset-选择
Server ACL- dbsize -flushall -flushdb -time
Scripting eval -evalsha-存在 - 脚本 - 脚本加载 - 脚本齐平
Pub/Sub 订阅-psubscribe -unsubscribe -punsubscribe-出版 - pubsub
Cluster
Geo
HyperLogLog
Stream

转到Upstash Redis® API Compatibility检查最新版本。

玩的时间到了

创建应用程序

让我们开始创建Rails应用程序并集成了Upstash Redis。因为我们要创建铁轨应用程序,所以我们需要确保在您的计算机中安装Ruby。

$ ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]

$ rails -v
Rails 7.0.4

我使用Ruby 3.1.2,这是最新的稳定版本和Rails 7.0版本。让我们首先创建应用程序

$ rails new try-upstash

此命令将使用默认设置创建Rails应用程序。

现在在应用程序中安装redis ruby​​,打开Gemfile,然后添加redis gem

gem "redis", "~> 5.0"

打开终端并运行bundle install安装宝石。

现在是时候创建一些模型并创建一些数据了。

# create product model
$ rails g model Product name description:text price:float
      invoke  active_record
      create    db/migrate/20221229082154_create_products.rb
      create    app/models/product.rb
      invoke    test_unit
      create      test/models/product_test.rb
      create      test/fixtures/products.yml

# create user model
$ rails g model User email:string:uniq name
      invoke  active_record
      create    db/migrate/20221229084021_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml

打开db/seeds.rb并为产品和用户模型创建一些数据

# Create 10 products
(1..10).each do |i|
  Product.create(name: "Product #{i}", price: 100, description: "Description")
end

# Create 3 users
(1..3).each do |i|
  User.create(email: "email#{i}@example.com", name: "User #{i}")
end

然后通过在终端中运行rails db:seed来运行种子。为了确保创建数据,我们可以使用GUI数据库或使用Rails Console。目前,我将使用Rails控制台,打开您的终端,然后键入rails c,您将看到Rails Console,并且可以在此控制台中运行Ruby Script或Rails特定命令。让我们尝试获取产品和用户的总数。

Total Users and Products

数据库种子是成功的,现在我们有10种产品和3个用户。

#1用例 - 在Upstash Redis中保存模型属性

想象您的应用程序需要存储布尔值,以指示用户是否正在完成入门过程。您可以在表名为onboarded的表中添加一个新列,并带有类型的boolean,并且每次要验证入职时,您都会经常访问表。如果您没有很多数据并且流量不高,这很好。但是,您的应用程序正在增长,应用程序开始缓慢。这里的解决方案之一是将onboarded值保存在REDIS数据库中,并且由于Redis将数据存储在内存而不是将数据存储在磁盘上,因此您将获得最高的速度和性能。您可能有这样的问题

如果服务器崩溃,会丢失重新数字吗?

答案取决于您正在使用的redis云,但是在这种情况下,如果您使用的是Upstash Redis,则数据将仍在耐用的存储中,例如AWS中的EBS。在UpStash中,如果服务器崩溃,将数据从块存储中重新加载到内存。 Upstash还提供Multi Zone Replication,为您提供高可用性和更好的可扩展性,可以为所有付费用户启用。

让我们回到应用程序,打开Gemfile并添加kredisdotenv

gem "kredis", "~> 1.3"
gem "dotenv-rails"

运行bundle install,然后用./bin/rails kredis:install启动kredis。这将在config/redis/shared.yml中创建一个文件。您可以在此文件中配置REDIS连接。默认情况下,配置将在开发和生产环境中读取ENV变量REDIS_URL,以及默认连接redis://127.0.0.1:6379/0如果ENV变量不存在。

development: &development
  url: <%= ENV.fetch("REDIS_URL", "redis://127.0.0.1:6379/0") %>
  timeout: 1

现在,对于env文件,在root项目中创建.env,然后添加REDIS_URL变量。您需要从数据库详细信息中获取值。

Upstash URL Connection

然后将redis://更改为rediss://,以便将TLS用于连接

REDIS_URL=<valuehere>

现在连接已完成,回到我们要为每个用户保存onboarded状态的用例。在这种情况下,我们将使用kredis,以通过将Redis数据库连接到应用程序模型来使我们的生活更轻松。打开用户模型app/models/user.rb,然后添加kredis_boolean属性,因为我们需要的类型是布尔。

class User < ApplicationRecord
  kredis_boolean :onboarded
end

如果您需要除布尔类型以外的其他需要,则在kredis中,我们可以使用listunique_listenumcounter等。

现在,您在实例模型中拥有onboarded方法。让我们在栏杆控制台中尝试一下。

  • 打开终端并运行rails c
  • u = User.first抓住第一个用户

First User rails console

  • 现在,您拥有了使用ID 1的第一个用户的用户模型实例。您可以使用u.onboarded.value从redis数据库中获取onboarded

Onboarded value

您可以看到,Kredis将使用格式model_name_plural:id:attribute_name自动为用户映射密钥。您可以在kredis repo中找到它。

默认值是nil,我们希望根据我们的需求将值更改为truefalse

  • onboarded值设置为true,因为用户已经完成了入职

Onboarded value 2

  • 为了确保该值已更改,您可以使用先前的命令获取onboarded的值

Onboarded value 3

  • 现在onboardedtrue,这意味着用户已经完成了入职。

在UpStash中,您还可以使用数据浏览器功能查看已插入REDIS数据库的所有数据。返回到Upstash控制台,然后单击您的REDIS数据库。您将看到数据浏览器。您可以根据密钥查看值,删除并设置数据密钥的到期。

Upstash Data Browser

或如果您想尝试使用redis cli获取值,请切换到 cli 页面,然后可以在此输入命令。例如,我想获得第一个用户的值,然后使用GET命令。

Upstash CLI

因此,在您的应用程序中,如果要检查用户是否入门,只需检查onboarded属性的值,并且可用于用户模型的实例。

u = User.first
if u.onboarded.value
  # run some code if the user is onboarded
else
  # run some code if the user has not been onboarded
end

#2用例 - 带有Upstash Redis的缓存

在第二种用例中,我们将用upstash redis进行缓存。让我们考虑到我们需要缓存特定值或来自外部应用程序(API)的某些查询。通常,API的响应是JSON对象,我们希望它在一段时间内缓存结果并将其保存到REDIS数据库。在这种情况下,我们可以使用Rails.cache.fetch方法在轨道中使用低级缓存。此方法同时将其写入和阅读给缓存。只要信息像JSON一样可序列化,Rails Cache可以正常工作。

这是一个示例,请考虑我们有产品,每个产品实例都有从其他网站或API查找竞争对手价格的方法,然后我们只想将其保存在8小时之后,该值不再存在。数据库。

首先,将缓存存储配置为使用Redis作为数据库。打开开发环境文件config/environments/development.rb并将商店更改为redis

- config.cache_store = :memory_store
+ config.cache_store = :redis_cache_store, { url: ENV["REDIS_URL"] }

并且由于默认情况下的开发环境中的缓存,因此为了测试目的,我们需要使用命令rails dev:cache

启用它

Enable cache

让产品在产品模型中添加competitor_price

class Product < ApplicationRecord
  def competitor_price
    Rails.cache.fetch("#{cache_key_with_version}/competitor_price", expires_in: 8.hours) do
      # call the API here
    end
  end
end

这是我们用例的基本用法。因此,这是它的工作原理,当您调用competitor_price时,将在数据库中不可用或缓存键已过期的情况下执行块给定的缓存键。

因此,在这种情况下,当第一次致电competitor_price时,它将致电API,并且API的结果将写入缓存,第二次您致电competitor_price时,它将从缓存中获得值,并在8小时之后缓存。键将自动删除。

cache_key_with_version是一种导轨方法,它基于模型的类名称,idupdated_at属性生成高速缓存键。因此,由此产生的缓存键将是products/1-20221229085409206814/competitor_price

之类的东西

对于测试,让我们更新competitor_price方法并将到期更改为30秒,然后从块中编写静态值

class Product < ApplicationRecord
  def competitor_price
    Rails.cache.fetch("#{cache_key_with_version}/competitor_price", expires_in: 30.seconds) do
      sleep 3
      {
        "prices": [
          { "name": "Amazon", "price": 12.00 },
          { "name": "Ebay", "price": 11.00 },
        ]
      }
    end
  end
end

您可能会注意到我添加了sleep 3来说明调用外部API时的过程。

让我们在轨道控制台中尝试,打开终端并运行rails c

  • 首先抓住第一个产品并分配到可变product

First product

  • 现在,使用product.competitor_price致电competitor_price,您会注意到,完成该过程的大约3秒钟将需要一些时间,因为这是第一次执行块。请记住,我们之前添加了sleep 3

calls method

  • 现在让我们再次调用该方法,并且不会执行块,而是将结果值来自缓存。您不需要等待3秒才能获得价值。
  • 和30秒后,将自动删除缓存键。您可以在UpStash Console中检查数据浏览器

当您需要缓存特定的查询或值时,此方法很有用,并且需要在应用程序中经常获得该值而不牺牲响应时间。

概括

Upstash Redis是compatible,几乎所有Redis API,可用于流行用例,例如:

  • 查询缓存
  • 会话缓存
  • 消息经纪
  • 队列等

UpStash Redis也可以用作数据库,而不必担心如果服务器崩溃,则要归功于Durable StorageUpstash Global Database复制数据库并分布在多个区域,并将用户路由到最近的区域以最大程度地减少延迟并优化性能。

参考