2013-09-16 12 views
6

Ho un'app Rails 3.2 che sta servendo contenuti obsoleti. Uno scenario tipico:L'app Rails 3.2 sembra memorizzare nella cache le query tra le richieste?

  1. un admin aggiunge alcuni nuovi record nel back-end
  2. utente va a visualizzare la pagina di indice per quelle risorse
  3. che non appaiono sulla pagina
  4. hanno ricaricare; le risorse sono ora disponibili
  5. aggiornate; le risorse non sono lì
  6. ecc

ho creato un modello/regolatore/vista così ho potuto testare il tutto:

# 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 %> 

Ho anche un piccolo script di shell in esecuzione che aggiunge periodicamente record alla tabella cache_query_tests nel database MySQL dell'app in modo che, in teoria, il database non stia interrogando la cache.

Quando mi ha colpito l'URL che visualizza la mia pagina di prova, ottengo un mix di risultati, come:

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

o:

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

o:

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

e così via ...

In tutto ca ses, il "Ruby Time" è attuale e corretto, quindi la pagina stessa non viene memorizzata nella cache. Tuttavia, come puoi vedere, "Rails MySQL Time" spesso non è sincronizzato con Ruby Time. Inoltre, "Rails MySQL Count" è abbastanza spesso sbagliato, nonostante io aggiunga record al database, quindi questo è il motivo per cui penso che qualcosa all'interno dello stack di Rails stia eseguendo il caching delle query.

In base alle mie conoscenze, Rails deve solo eseguire query caching within a request. Qui, qualcosa (forse MySQL? Forse Rack? Forse Rails?) Lo sta facendo attraverso le richieste. Francamente, sono abbastanza perplesso su dove andare da qui. Mentre mi piacerebbe una soluzione :), mi piacerebbe anche qualche altra opinione su dove potrebbe trovarsi il problema.

Grazie.

risposta

0

Solo per aiutare SOB sfortunato che finisce qui con lo stesso problema, alla fine abbiamo rintracciato questo gioiello Octopus (https://github.com/tchandy/octopus). Si noti che non sono sicuro se questo comportamento è inteso o configurabile, quindi non voglio incolpare Octopus, ma piuttosto notare che questa è stata la causa.

0

Anche se è difficile dirlo con certezza (poiché questo dipende dalla configurazione di MySQL, non dalla configurazione di Rails), la risposta più probabile è che il server MySQL stia usando query cache. Dalla documentazione:

la cache negozi di query il testo di una SELECT insieme il corrispondente risultato che è stato inviato al client. Se viene ricevuta in seguito un'identica dichiarazione , il server recupera i risultati dalla cache delle query anziché analizzare ed eseguire nuovamente l'istruzione. La cache delle query è condivisa tra le sessioni, quindi un set di risultati generato da un client può essere inviato in risposta alla stessa query emessa da un altro client .

È possibile verificare se ciò si verifica o meno sul livello del database utilizzando query cache select options. Provare a cambiare l'istruzione SQL a qualcosa di simile:

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

Scommetto poi ci si accorge che il tempo cambia ogni volta che si recupera.

+0

In base alla [documentazione di caching di MySQL] (http://dev.mysql.com/doc/refman/5.6/en/query-cache-operation.html), MySQL non deve memorizzare le query nella cache con NOW () in essi, e si suppone che cancelli la cache quando i record sono INSERITI (come sto facendo). Comunque, ci provo io. Grazie. – Marc

+0

Solo per dare seguito a quanto sopra, non ha funzionato :( – Marc

Problemi correlati