小编Nie*_*ian的帖子

是否可以在 rails 中有多个数据库连接池来切换?

一点背景

多年来,我一直在使用Apartment gem来运行多租户应用程序。现在最近需要将数据库扩展到单独的主机上,数据库服务器根本无法跟上(读取和写入都变得太多) - 是的,我将硬件扩展到最大(专用硬件、64 核、raid 10 中的 12 个 Nvm-e 驱动器、384Gb ram 等)。

我正在考虑按租户执行此操作(1 个租户 = 1 个数据库连接配置/池),因为这将是一种“简单”且有效的方法,可以在number-of-tenants不进行大量应用程序代码更改的情况下获得更多的容量。

现在,我正在运行 rails 4.2 atm.,很快升级到 5.2。我可以看到 rails 6 添加了对每个模型连接定义的支持,但这并不是我真正需要的,因为我为我的 20 个租户中的每个租户都有一个完全镜像的数据库模式。通常我会根据请求(在中间件中)或每个后台作业(sidekiq 中间件)切换“数据库”,但是目前这很简单,并且可以在 Apartment gem 中处理,因为它只是search_path在 Postgresql 中设置了并且并没有真正改变实际连接。当切换到每租户托管策略时,我需要根据请求切换整个连接。

问题:

  1. 我知道我可以执行ActiveRecord::Base.establish_connection(config)每个请求/后台工作 - 但是,正如我所理解的,这会触发一个全新的数据库连接握手,并在 Rails 中生成一个新的数据库池 - 对吗?我想这将是性能自杀,在对我的应用程序的每个请求上都产生这种开销。
  2. 因此,我想知道是否有人可以看到带有 Rails 的选项,例如从一开始(例如在应用程序启动时)预先建立多个(总共 20 个)数据库连接/池,然后根据请求在这些池之间切换?这样他的数据库连接就已经建立并可以使用了。
  3. 这一切只是一个糟糕的主意吗,我应该寻找不同的方法吗?例如,1 个应用程序实例 = 到一个特定租户的一个特定连接。或者是其他东西。

ruby postgresql ruby-on-rails multi-tenant

13
推荐指数
1
解决办法
1190
查看次数

即使一个图像的裁剪/比例略有不同,我如何检测两个图像是“相同的”?

我有两个不同的图像:

在 100px 与 在此处输入图片说明 或 400 像素 在此处输入图片说明

在 100px 宽度 在此处输入图片说明 或 400 像素 在此处输入图片说明

正如您所看到的,从人类的角度来看,两者显然是“相同的”。现在我想以编程方式检测它们是否相同。我一直在通过 ruby​​ gem 使用图像魔法,rmagick如下所示:

img1 = Magick::Image.from_blob(File.read("image_1.jpeg")).first
img2 = Magick::Image.from_blob(File.read("image_2.jpeg")).first

if img1.difference(img2).first < 4000.0 # I have found this to be a good threshold, but does not work for cropped images
  puts "they are the same!!!"
end
Run Code Online (Sandbox Code Playgroud)

虽然这适用于具有相同比例/裁剪的图像,但当它们的裁剪略有不同并且已调整为相同宽度时,这并不理想。

有没有办法对不同裁剪的图像进行处理?我对一个解决方案感兴趣,我可以这样说:一个图像包含在另一个图像中,并覆盖了大约 90% 的区域。

附注。如果有帮助,我可以获得更高分辨率的图像(例如双倍)

ruby rmagick image-comparison imagemagick image-processing

11
推荐指数
1
解决办法
955
查看次数

在rails中进行大量数据迁移

在进行大数据迁移(几十万行)时,我遇到了巨大的时间和计算能力挑战.我正在开发一种处理rails中大量数据的服务.随着我们对设计的关注越来越多,我们的模型也在不断变化.这导致我们的数据库(Postgres 9.0数据库)进行了大量迁移.这些迁移通常还包括对数据本身的某种迁移.昨天我们发现我们需要将模型上的"text"属性移动到一个单独的模型中,这样该属性不再仅仅是模型上的属性,而是一对多关系.

我的迁移看起来有点像这样:

def self.up
  create_table :car_descriptions do |t|
    t.integer :car_id
    t.text :description

    t.timestamps
  end

  Car.find_each do |car|
    if car.description.present?
      car.descriptions.build :description => car.description
    end
    car.save
  end
  remove_column :cars, :description
end
Run Code Online (Sandbox Code Playgroud)

现在的问题是,这种运行速度非常慢,更糟糕的是,如果我设置一个计数器并打印出进度,我可以看到迁移的运行速度越来越慢.在我的活动监视器中,我可以看到ruby进程占用了越来越多的内存.

所以我的问题是 - 有更好的方法来进行这样的大数据迁移吗?

database data-migration ruby-on-rails

7
推荐指数
1
解决办法
1085
查看次数

解析/读取大型XML文件,占用内存最少

我有一个非常大的XML文件(300mb),格式如下:

<data>
 <point>
  <id><![CDATA[1371308]]></id>
  <time><![CDATA[15:36]]></time>
 </point>
 <point>
  <id><![CDATA[1371308]]></id>
  <time><![CDATA[15:36]]></time>
 </point>
 <point>
  <id><![CDATA[1371308]]></id>
  <time><![CDATA[15:36]]></time>
 </point>
</data>
Run Code Online (Sandbox Code Playgroud)

现在我需要读取它并遍历point节点为每个节点做一些事情.目前我正在和Nokogiri这样做:

require 'nokogiri'
xmlfeed = Nokogiri::XML(open("large_file.xml"))
xmlfeed.xpath("./data/point").each do |item|
  save_id(item.xpath("./id").text)
end
Run Code Online (Sandbox Code Playgroud)

然而,这并不是非常有效,因为它解析了整个拥抱的一切,因此创造了巨大的内存占用(几GB).

有没有办法在块中执行此操作?如果我没弄错的话可能会被称为流式传输?

编辑

使用nokogiris sax解析器的建议答案可能没问题,但是当每个节点中有多个节点point需要从中提取内容并以不同方式处理时,它会变得非常混乱.我宁愿选择point一次访问一个,处理它,然后继续下一个"忘记"前一个,而不是返回大量的条目供以后处理.

ruby xml-parsing

7
推荐指数
1
解决办法
2664
查看次数

是否可以从用户代理中识别华为设备是否不支持谷歌服务?

我想在我的 Google Analytics 中检查我的用户群中有多大比例使用华为设备,这些设备不再使用谷歌服务,而是使用应用程序库等。

我想知道我是否可以在用户代理等中查找特定的操作系统版本?

user-agent google-analytics huawei-mobile-services huawei-developers

7
推荐指数
1
解决办法
3936
查看次数

是否可以在rabl视图中进行片段缓存?

我正在尝试做这样的事情:

cache "api/v1/cars_index/#{I18n.locale}/car/#{car.cache_key}" do
  attributes :id, :brand, :model_name, :fuel, :km, :year, :price
  node(:color) { |car| car.color.present? ? car.color : '' }
end
Run Code Online (Sandbox Code Playgroud)

api caching ruby-on-rails rabl

6
推荐指数
1
解决办法
747
查看次数

如何从sidekiq管理到PostgreSQL的连接池?

问题我有一个运行几百个sidekiq后台进程的rails应用程序.它们都连接到一个PostgreSQL数据库,它对提供250个连接并不十分满意 - 它可以,但如果所有sidekiq进程意外地向db发送查询,它就会崩溃.

选项1我一直在考虑在数据库前添加pgBouncer,但我目前无法使用它的事务模式,因为我高度依赖于search_path在每个作业处理的开头设置以确定哪个"国家"(PostgreSQL模式)工作(公寓宝石).在这种情况下,我将不得不使用基于会话的连接池模式.然而,据我所知,这会要求我在每次作业处理后断开连接,将连接释放回池中,这样做性能真的很高,不是吗?我错过了什么吗?

选项2使用基于应用程序层的连接池也是一个选项,但是我不确定我如何能够使用sidekiq为PostgreSQL做到这一点?

选项3我没有想到的东西?

postgresql connection-pooling pgbouncer sidekiq apartment-gem

6
推荐指数
1
解决办法
1018
查看次数

DynamoDB:我将属性设置为"NULL":"true"或者只是省略它会有什么不同?

我有一些像这样插入的项目:

PutItem:

"TableName": "pets",
"Item": {
  "petName": {
      "S": "Cat"
    },
  "hairColor": {
      "S": "gray"
    },
  "nickName": {
      "S": "Kitty"
    }
 }
Run Code Online (Sandbox Code Playgroud)

然而,有时候,pets没有nickname.我对dynamoDB很新,我可以看到,我可以通过两种方式处理这个问题(至少):

1)

"TableName": "pets",
"Item": {
  "petName": {
      "S": "Cat"
    },
  "hairColor": {
      "S": "gray"
    },
  "nickName": {
      "NULL": "true"
    }
 }
Run Code Online (Sandbox Code Playgroud)

2)

"TableName": "pets",
"Item": {
  "petName": {
      "S": "Cat"
    },
  "hairColor": {
      "S": "gray"
    }
 }
Run Code Online (Sandbox Code Playgroud)

这会给我带来什么不同(例如,之后访问数据时)?什么是最佳做法?

amazon-dynamodb

6
推荐指数
1
解决办法
999
查看次数

如何在postgresql中创建多列推荐引擎?

我在postgresql中有一个包含一些汽车+1000000记录的表:

+----+--------+------+---------+-----------+-------------+------------+------------+
| id |  price | year | mileage | fuel_type |  body_type  |   brand    |   model    |
+----+--------+------+---------+-----------+-------------+------------+------------+
|  1 |   4894 | 2011 |  121842 | "Benzin"  | "Sedan"     | "Toyota"   | "Yaris"    |
|  2 |   4989 | 2012 |   33901 | "Benzin"  | "Hatchback" | "Renault"  | "Twingo"   |
|  3 |   4990 | 2013 |   55105 | "Benzin"  | "Hatchback" | "Renault"  | "Twingo"   |
|  3 |   5290 | 2013 |   20967 | …
Run Code Online (Sandbox Code Playgroud)

ruby postgresql recommendation-engine

6
推荐指数
2
解决办法
366
查看次数

Tinc/SHH/IPSec:调整高吞吐量

我有一个运行memcached的专用128GB ram服务器.4个Web服务器连接到那个.它们总共发送大约20k包/秒.

最近我决定改变从web服务器到memcached服务器的连接,从持久的SSH隧道到使用Tinc(为了简化设置和灵活性,只要我需要它们在新端口上进行通信).

在此输入图像描述

这种变化导致网络往返的开销显着增加(见图表).然而,我注意到,使用Tinc支持SSH隧道的网络开销要小得多(甚至比之前的SSH隧道还要快!),当我用它在服务器之间进行通信时(例如我的Postgresql数据库服务器),吞吐量低很多<每秒10k数据包.我试图在更多服务器之间分配memcached负载,突然来自tinc/network的开销显着下降.

现在,我不明白为什么tinc网络开销会随着吞吐量的增加而急剧增加?这就像我打了一个瓶颈(并且它肯定不是CPU,因为Newrelic报告<tinc过程的使用率<0.5%).有什么东西我可以在Tinc设置中调整,还是Tinc只是高吞吐量的坏选择?我应该使用IPsec吗?

ssh ipsec ssh-tunnel tinc

6
推荐指数
0
解决办法
737
查看次数