2012-10-15 2 views
12

heroku 웹 dyno가 사용하는 메모리 양을 알아낼 방법이 있습니까? 정기적으로 실행되는 레이크 작업을 작성하고 모든 dyno의 메모리 사용량을 확인한다고 가정 해 봅시다. 내가 어떻게 할 수 있니? 감사!Rails 3 + Heroku : dyno의 메모리 사용량을 알아보십시오

+1

새로운 유물을 사용하지 않는 이유가 거기에 그것은 다음과 같이 보입니다? 모니터링> Dynos –

+1

모든 dynos 조합의 최소, 최대 및 평균 메모리 사용량을 보여줍니다. 특정 dyno의 메모리를 검색하는 방법이 없습니다. – sauronnikko

답변

3

Heroku는 Linux로 Amazon 인스턴스에서 실행되므로 proc 파일 시스템을 사용하여 런타임 시스템 데이터를 얻을 수 있습니다. 파일에는 실행중인 프로세스와로드되는 모든 라이브러리에 대한 메모리 정보가 들어 있습니다. 상주 프로세스 크기의 경우, 다음을 수행하십시오

f = File.open("/proc/#{Process.pid}/smaps") 
f.gets # Throw away first line 
l = f.gets # Contains a string like "Size:    2148 kB\n" 
l =~ /(\d+) kB/ # match the size in kB 
f.close 
$1.to_i # returns matched size as integer 

업데이트 : proc 파일 시스템은 더 나은 소스, /proc/<pid>/status있다. 총 상주 메모리 부분에 대해 VmRSS: 엔트리가 있고 사용 된 가장 높은 상주 메모리에 대해 VmHWM: (최고 수위 마크)이 있습니다. 이러한 필드 및 기타 필드에 대한 자세한 내용은 The Linux Kernel docs for the proc file system을 참조하십시오.

+0

Heroku의 Cedar 스택에서 첫 번째 라이브러리의 크기를 반환합니다 프로세스 자체가 아닙니다. 아마도 모든 크기를 반복하고 합칠 필요가있을 것입니다. – Sim

+0

시더에 대한 설명을 주셔서 감사합니다. –

6

나는 받아 들인 대답에서 제안을 취하고 집계 & 임계 값 기반 diffing을 가진/proc 파일 시스템 구문 분석기를 구현했습니다. 내가 Heroku에서 Ruby 2.0 메모리 문제를 디버깅하는 데 매우 유용하다는 것을 알았습니다. 편의상 여기에 포함 된 code을 받으십시오.

# Memory snapshot analyzer which parses the /proc file system on *nix 
# 
# Example (run in Heroku console): 
# 
# ms = MemorySnapshot.new 
# 1.upto(10000).map { |i| Array.new(i) }; nil 
# ms.snapshot!; nil 
# ms.diff 10 
# => {"lib/ld-2.11.1.so"=>156, "heap"=>2068, "all"=>2224} 
# 
class MemorySnapshot 

    attr_reader :previous 
    attr_reader :current 

    def initialize 
    snapshot! 
    @previous = @current 
    end 

    # Generates a Hash of memory elements mapped to sizes of the elements in Kb 
    def snapshot! 
    @previous = @current 
    @current = reduce(names_with_sizes) 
    end 

    # Calculates the difference between the previous and the current snapshot 
    # Threshold is a minimum delta in kilobytes required to include an entry 
    def diff(threshold = 0) 
    self.class.diff_between previous, current, threshold 
    end 

    # Calculates the difference between two memory snapshots 
    # Threshold is a minimum delta in kilobytes required to include an entry 
    def self.diff_between(before, after, threshold) 
    names = (before.keys + after.keys).uniq 
    names.reduce({}) do |memo, name| 
     delta = after.fetch(name) { 0 } - before.fetch(name) { 0 } 
     memo[name] = delta if delta.abs >= threshold 
     memo 
    end 
    end 

    private 

    def reduce(matches) 
    total = 0 
    current_name = nil 
    matches.reduce(Hash.new { 0 }) do |memo, match| 
     current_name = match[:name] || current_name 
     size = match[:size].to_i 
     total += size 
     memo[current_name] += size 
     memo 
    end.tap { |snapshot| snapshot['all'] = total } 
    end 

    def names_with_sizes 
    smap_entries.map do |line| 
     /((^(\/|\[)(?<name>[^ \]]+)\]?\s+)|(^))(?<size>\d+)\s/.match(line) 
    end 
    end 

    def smap_entries 
    smaps. 
     gsub(/^(([^Sa-f0-9])|(S[^i]))[^\n]+\n/m, ''). 
     gsub(/\nSize:/m, ''). 
     gsub(/[0-9a-f]+-[0-9a-f]+.{6}[0-9a-f]+ [0-9a-f]+:[0-9a-f]+ [0-9a-f]+\s+/i, ''). 
     split("\n") 
    end 

    def smaps 
    File.read("/proc/#{Process.pid}/smaps") 
    end 
end 
5

여기에도 기본 헤로 쿠 방식이 있습니다. Heroku는 실험실 기능 log runtime metrics을 출시했습니다.이 도구는 CPU로드 및 메모리 사용 정보를 로깅 스트림에 주입합니다. 이 로그에는 소스 ID (예 : 'web.1')와 dyno 고유 ID가있어 사용자가 dynos를 구분할 수 있습니다.

source=web.1 dyno=heroku.2808254.d97d0ea7-cf3d-411b-b453-d2943a50b456 sample#load_avg_1m=2.46 sample#load_avg_5m=1.06 sample#load_avg_15m=0.99 
source=web.1 dyno=heroku.2808254.d97d0ea7-cf3d-411b-b453-d2943a50b456 sample#memory_total=21.00MB sample#memory_rss=21.22MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=348836pages sample#memory_pgpgout=343403pages 

에이를 설정하려면 실행 :

heroku labs:enable log-runtime-metrics 
heroku restart