Python作成memcached起動スクリプトコードの例


memcachedは分散型のキャッシュシステムで、LiveJournalのBrad Fitzpatrickによって開発されましたが、多くのサイトで使用されています。これはオープンソースコードソフトウェアのセットです。
memcachedは認証と安全管理が不足しています。これはmemcachedサーバをファイアウォールの後に置くべきです。
memcachedのAPIは32ビットの巡回冗長検査(CRC-32)を使ってキー値を計算し、データを異なるマシンに分散させる。テーブルがいっぱいになったら、次に追加されたデータはLRU方式で置き換えられます。memcachedは通常はキャッシュシステムとしてのみ使用されるので、memcachedのアプリケーションを使用して、遅いシステムに返信するとき(バックエンドのデータベースのような)、memcached内のデータを追加のコードで更新する必要があります。
memcachedはキャッシュファイルサービスとして、デフォルトはオペレーティングシステムの中で直接yum-y install memcachedをインストールすることができます。
/etc/init.d/memcachedはシステムshellで作成された管理スクリプトです。以下のこのスクリプトはpythonスクリプトで作成されたmemcached管理スクリプトで、shellで作成されたスクリプトと同じ効果があります。
コードは以下の通りです

#!/usr/bin/python

import sys
import os
from subprocess import Popen,PIPE

class Process(object):
  '''memached rc script'''
  args = {'USER':'memcached',
      'PORT':11211,
      'MAXCONN':1024,
      'CACHESIZE':64,
      'OPTION':''}

  def __init__(self,name,program,workdir):
    self.name = name
    self.program = program
    self.workdir = workdir

  def _init(self):
    '''/var/tmp/memcached'''
    if not os.path.exists(self.workdir):
      os.mkdir(self.workdir)
      os.chdir(self.workdir)

  def _pidFile(self):
    '''/var/tmp/memcached/memcached.pid'''
    return os.path.join(self.workdir, "%s.pid" % self.name)

  def _writePid(self):
    if self.pid:
      with open(self._pidFile(),'w') as fd:
        fd.write(str(self.pid))


  def _readConf(self,f):
    with open(f) as fd:
      lines = fd.readlines()
      return dict([ i.strip().replace('"','').split('=') for i in lines])

  def _parseArgs(self):
    conf = self._readConf('/etc/sysconfig/memcached')       
    if 'USER' in conf:
      self.args['USER'] = conf['USER']
    if 'PORT' in conf:
      self.args['PORT'] = conf['PORT']
    if 'MAXCONN' in conf:
      self.args['MAXCONN'] = conf['MAXCONN']
    if 'CACHESIZE' in conf:
      self.args['CACHESIZE'] = conf['CACHESIZE']
    options = ['-u',self.args['USER'],
          '-p',self.args['PORT'],
          '-m',self.args['CACHESIZE'],
          '-c',self.args['MAXCONN']]
    os.system("chown %s %s" % (self.args['USER'],self.workdir))
    return options

  def start(self):
    pid = self._getPid()
    if pid:
      print "%s is running..." % self.name
      sys.exit()
    self._init()
    cmd = [self.program] + self._parseArgs() + ['-d','-P',self._pidFile()]
    p = Popen(cmd,stdout=PIPE)
    #self.pid = p.pid
    #self._writePid()
    print "%s start Sucessful \t\t [OK]" % self.name

  def _getPid(self):
    p = Popen(['pidof',self.name],stdout=PIPE)
    pid = p.stdout.read().strip()
    return pid

  def stop(self):
    pid = self._getPid()
    if pid:
      os.kill(int(pid),15)
      if os.path.exists(self._pidFile()):
        os.remove(self._pidFile())
      print "%s is stopped \t\t\t [OK]" % self.name

  def restart(self):
    self.stop()
    self.start()
    

  def status(self):
    pid = self._getPid()
    if pid:
      print "%s is already running" % self.name
    else:
      print "%s is not running" % self.name

  def help(self):
    print "Usage:%s {start|stop|status|restart|} " % __file__

  
def main():
  name = 'memcached'
  prog = '/usr/bin/memcached'
  args = '-u nobody -p 11211 -c 1024 -m 64' 
  wd = '/var/tmp/memcached'
  pm = Process(name = name,
         program = prog,
         workdir = wd)
  try:
    cmd = sys.argv[1]
  except IndexError,e:
    print "Option error"
    sys.exit()
  if cmd == 'start':
    pm.start()
  elif cmd == 'stop':
    pm.stop()
  elif cmd == 'restart':
    pm.restart()
  elif cmd == 'status':
    pm.status()
  else:
    pm.help()

if __name__ == '__main__':
  main()
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。