2013-09-16 4 views
6

Ich habe eine Rails 3.2 App, die veralteten Inhalt dient. Ein typisches Szenario:Rails 3.2 App scheint Abfragen zwischen Anfragen zu cachen?

  1. ein Admin fügt einige neue Datensätze in der Back-End-
  2. Benutzer die Indexseite für diese Ressourcen
  3. sie nicht zeigen, auf der Seite nach oben zu betrachten geht
  4. sie Aktualisierung; die Ressourcen sind jetzt da
  5. sie aktualisieren; die Mittel sind nicht dazu da
  6. usw.

ich ein Modell/Controller/Ansicht erstellt, so konnte ich dies testen:

# app/models/cache_query_test.rb 

class CacheQueryTest < ActiveRecord::Base 
end 

# app/controllers/cache_query_tests_controller.rb 

class CacheQueryTestsController < ApplicationController 
    def count 
    @count = CacheQueryTest.count 
    @mysql_time = CacheQueryTest.find_by_sql("SELECT NOW() AS mysql_time") 

    respond_to do |wants| 
     wants.text { render :layout => false } 
    end 
    end 
end 

# app/views/cache_query_tests/count.text.erb 

============== 
Rails MySQL Time: <%= @mysql_time.first.mysql_time %> 
Ruby Time:  <%= Time.now.strftime "%Y-%m-%d %H:%M:%S" %> 
Rails MySQL Count: <%= @count %> 

Ich habe auch ein kleines Shell-Skript, dass in regelmäßigen Abständen fügt Datensätze läuft in die Tabelle cache_query_tests in der MySQL-Datenbank der Anwendung, sodass die Datenbank theoretisch keine Abfragen zwischenspeichert.

Wenn ich die URL getroffen, dass meine Testseite zeigt, erhalte ich eine gemischte Tüte Ergebnisse, wie:

============== 
Rails MySQL Time: Mon Sep 16 10:40:57 UTC 2013 
Ruby Time:  2013-09-16 10:40:58 
Rails MySQL Count: 177 

oder:

============== 
Rails MySQL Time: Mon Sep 16 09:47:46 UTC 2013 
Ruby Time:  2013-09-16 10:16:32 
Rails MySQL Count: 165 

oder:

============== 
Rails MySQL Time: Mon Sep 16 09:50:02 UTC 2013 
Ruby Time:  2013-09-16 10:41:32 
Rails MySQL Count: 167 

und so weiter ...

In allen ca ses ist die "Ruby Time" aktuell und korrekt, so dass die Seite selbst nicht zwischengespeichert wird. Wie Sie jedoch sehen, ist die "Rails MySQL Time" oft nicht mit der Ruby Time synchronisiert. Auch die "Rails MySQL-Anzahl" ist ziemlich oft falsch, trotz der Tatsache, dass ich Datensätze zur Datenbank hinzufüge, deshalb denke ich, dass etwas innerhalb des Rails-Stapels Abfrage-Caching durchführt.

Soweit ich weiß, sollte Rails nur query caching within a request tun. Hier, etwas (vielleicht MySQL? Vielleicht Rack? Vielleicht Rails?) Macht es über Anfragen. Ehrlich gesagt bin ich ziemlich ratlos, wohin ich von hier aus gehen soll. Während ich eine Lösung lieben würde :), würde ich auch gerne mehr Meinungen darüber haben, wo das Problem liegen könnte.

Danke.

Antwort

0

Nur um jeden unglücklichen SOB, der hier mit dem gleichen Problem endet, zu helfen, verfolgten wir schließlich dieses auf den Octopus-Edelstein (https://github.com/tchandy/octopus). Beachten Sie, dass ich nicht sicher bin, ob dieses Verhalten beabsichtigt oder konfigurierbar ist, also möchte ich Octopus nicht die Schuld geben, sondern nur feststellen, dass dies die Ursache war.

0

Obwohl es schwer zu sagen ist (da dies von Ihrer MySQL-Konfiguration und nicht von Ihrer Rails-Konfiguration abhängt), lautet die wahrscheinlichste Antwort hier, dass Ihr MySQL-Server query cache verwendet. Aus der Dokumentation:

Der Abfragecache speichert den Text einer SELECT-Anweisung zusammen mit das entsprechende Ergebnis, das an den Client gesendet wurde. Wenn später eine identische -Anweisung empfangen wird, ruft der Server die Ergebnisse aus dem Abfragecache ab, statt die Anweisung erneut zu analysieren und auszuführen. Der Abfragecache wird unter Sitzungen gemeinsam genutzt, sodass eine Ergebnismenge, die von einem -Client generiert wird, als Antwort auf dieselbe Abfrage gesendet werden kann, die von einem anderen -Client ausgegeben wird.

Sie können mithilfe der query cache select options überprüfen, ob dies auf der Datenbankschicht auftritt. Versuchen Sie, Ihre SQL-Anweisung so etwas wie dies zu ändern:

@mysql_time = CacheQueryTest.find_by_sql("SELECT SQL_NO_CACHE NOW() AS mysql_time")

Ich wette, danach werden Sie feststellen, dass die Zeit, jedes Mal wenn Sie es abrufen ändert.

+0

Gemäß der [MySQL-Caching-Dokumentation] (http://dev.mysql.com/doc/refman/5.6/en/query-cache-operation.html) soll MySQL keine Abfragen mit NOW speichern () in ihnen, und soll den Cache löschen, wenn Datensätze eingefügt werden (wie ich es tue). Trotzdem werde ich es versuchen. Vielen Dank. – Marc

+0

Nur um das oben zu verfolgen, das hat nicht funktioniert :( – Marc