How can we improve the performance of RailS Applications ?, Improve rails

Source: Internet
Author: User

How can we improve the performance of RailS Applications ?, Improve rails

Is rails slow?

「 Railway is slow 」. You may have heard of this joke. What about our Rails framework?
If Rails is slow, how to improve the performance of Rails apps becomes a top concern for developers.

You may have heard of many ways to improve the performance of the RoR APP. They are difficult and easy to use. We need to select one of them to help developers get rid of the performance dilemma.

Here are several different ways to improve the performance of Rails Applications.

1. database index

Your APP is limited by database performance. Excellent database indexes can improve your performance by 100 times in large database tables. However, not all Rails developers understand how important this is.

It is easy to add indexes:

class AddIndexToClientIndustry < ActiveRecord::Migration    def change        add_index :client_industries, :client_id    endend

Next we will compare whether there is any Index.

If there is an Index:

CREATE INDEX addresses_addressable_id_addressable_type_idx  ONaddresses  USING btree  (addressable_id,addressable_type);t1 = Time.now c = Company.find(178389) a = c.addresses.firstt2 = Time.nowputs "---Operation took #{t2-t1} seconds---”Result with index:---Operation took 0.012412 seconds---

No Index:

DROP INDEXaddresses_addressable_id_addressable_type_idx;t1 = Time.now c = Company.find(178389) a = c.addresses.firstt2 = Time.nowputs "---Operation took #{t2-t1} seconds---”Result without index:---Operation took 0.378073 seconds---

0.378073/0.012412 = 30.46 no index is 30.46 seconds slower than indexing.

Therefore, engineers can add Indexes to all referenced parameters or other frequently queried parameters. However, you cannot add too much because each database increases the database Size, which affects performance.

2. Number of database queries

RoR makes programming faster, but in turn makes it difficult to control the number of database queries for each request. For example, if each Client has one or more Industries. We want to display the Client List and their Primary Industries:

<% @clients.each do |client| %>  <tr>      <td><%= client.id %></td>      <td><%= client.business_name %></td>      <td><%= client.industries.first.name %></td>  </tr><% end %># app/controllers/clients_controller.rbdef index    @clients = Client.allend

If there are 50 Clients, there will be 51 database queries:

    Processing by ClientsController#index as HTML    SELECT "clients".* FROM "clients"     SELECT "industries".* FROM "industries" INNER JOIN "client_industries" ON "industries"."id" = "client_industries"."industry_id" WHERE "client_industries"."client_id" = 1 LIMIT 1    SELECT "industries".* FROM "industries" INNER JOIN "client_industries" ON "industries"."id" = "client_industries"."industry_id" WHERE "client_industries"."client_id" = 2 LIMIT 1    SELECT "industries".* FROM "industries" INNER JOIN "client_industries" ON "industries"."id" = "client_industries"."industry_id" WHERE "client_industries"."client_id" = 3 LIMIT 1    …

Solution: Eager Loading

# app/controllers/clients_controller.rbdef index    @clients = Client.includes(:industries).allend

Currently, there are only 2 to 3 queries, not 51 queries:

    Processing by ClientsController#index as HTML    SELECT "clients".* FROM "clients"     SELECT "client_industries".* FROM    "client_industries" WHERE    "client_industries"."client_id" IN (1, 2, 3)    SELECT "industries".* FROM "industries" WHERE "industries"."id" IN (1, 5, 7, 8, 4)
3. Reduce memory usage
  • Only use the truly needed gem
  • Load objects during use
  • Batch Processing of massive data.

An example of using real data -- find_each:

Using find:
t1 = Time.now  Company.where(:country_id=>1).find do |c|puts "do something!" if ['Mattski Test'].include?(c.common_name)endt2 = Time.nowputs "---Operation took #{t2-t1} seconds---”
Result:
1 query, taking 46.65 seconds
Now using find_each:
t1 = Time.now  Company.where(:country_id=>1).find_each do |c|    puts "do something!" if ['Mattski Test'].include?(c.common_name)end  t2 = Time.nowputs "---Operation took #{t2-t1} seconds---"
Result:
100 queries, taking 15.53 seconds in total (3x faster)

There are also situations where the query speed is higher than the query speed.

4. Use Cache

The use of cache has a huge impact on performance. First, make sure that the data model is correct. The cache can help you hide structure problems.

  • Object Cache
    When the object cache is used, you should remove the include of the query method to avoid the association query's inability to use the cache.

  • Query Cache
    If real-time query is not required, you can use memcache-client to cache the query results to memcached.

  • Partial page Cache
    The object cache and query cache both reduce the database access load, but if the RoR load is high, you can only rely on partial page cache.

「 Web websites commonly use partial page caching. One drawback of partial page caching in Rails is that the query statement corresponding to the Action in the page query result should be placed in the View, otherwise, the query in each Action will still be executed, but this will damage the MVC structure of the program code. In this case, another Cache plug-in, better rails caching, can be used to Cache the query statements in Action while caching the page .」

5. Make web requests faster

Only a small number of available processes are used to serve web requests. Therefore, you need to make web requests faster. Ideally, the web process is generally completed within milliseconds. 1 to 2 seconds is slow, and more than 10 seconds is very slow. If your web request is slow, your Rails APP will not be able to support a large number of users at the same time.

Solution: run in the background
Run delayed jobs in the background for long-running projects to release your web process to solve more requests.

6. Performance monitoring

Monitor the performance of the APP to find out which part of the operation is slow or even locate the problem quickly. You can use the best OneAPM monitoring tool of domestic application performance monitoring.

OneAPM for Ruby can go deep into all Ruby applications to complete application performance management and monitoring, includingCode LevelVisibility of performance problems, fast identification and tracing of performance bottlenecks,Real User ExperienceMonitoring, server monitoring, and end-to-end application performance management. Tracing performance bottlenecks include SQL statements, third-party APIs, Web Services, Caching Layers, and background tasks with poor performance.

The figure shows the overview page using OneAPM for monitoring. Here, you can have a preliminary impression on the time consumption of requests on the server side. You can intuitively see indicators such as the flat response time, throughput, and execution times of web tasks, backend tasks, databases, and external services at different times. In the figure, the response time of web tasks peaked, slow response speed.

In order to further identify the problem, click the web transaction interface to further understand the proportion of slow Transaction Response Time and quickly locate the problem.api/medicines/indexThe response time is long.

Click the wrong request address to list the URL of the error, the first and last occurrence time, the number of errors, the Agent name, error information, and stack information.

Good application performance monitoring often requires a lot of time and effort to achieve, so selecting an excellent third-party monitoring tool will greatly improve the O & M efficiency, which is of great help to improve the performance of Rails apps.

7. Use a memory database

When the query and sorting are completed in the memory, the database will run faster, and they need to run slowly on the disk.

Solution:

  • Limit the size of the database to ensure it is fully suited to memory.
  • Remove non-urgent information from the primary database and to the secondary database or elsewhere.
  • If you need a large amount of storage, consider using non-relational databases.
8. More performance suggestions:
  • Use a content delivery network for static files, such as AWS CloudFront.
  • Use delayed loading for the add-on that takes 1-2 seconds.
  • Use the service-oriented architecture to synchronize some processes on the managed stack.

I believe that selecting one or more suitable performance improvement methods can make the RoR APP more satisfying to users.

Note: This article provides a reference and translation of some content shared by Matt Kuklinski on slideshare about improving Rails performance.

This article is compiled by OneAPM engineers. OneAPM is an emerging leader in the application performance management field. It helps enterprise users and developers easily achieve slow real-time crawling of program code and SQL statements. For more technical articles, visit the official OneAPM blog.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.