Gossip事始め
Upcoming SlideShare
Loading in...5
×
 

Gossip事始め

on

  • 2,990 views

第八回cassandra勉強会slideです。

第八回cassandra勉強会slideです。

Statistics

Views

Total Views
2,990
Views on SlideShare
2,990
Embed Views
0

Actions

Likes
1
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Gossip事始め Gossip事始め Presentation Transcript

    • Gossip事始め
      株式会社ムロドー
      とみたかずたか
    • アジェンダ
      Gossip事始め
      コードリーディングの準備
      デーモン起動
      起動準備
      デーモン初期化
      Gossip開始
    • コードリーディング下準備
      • Eclpseでstepbystep 実行を行う。
      用意するもの
      • 面倒くさいのでpleiadesonGlileo を用意
      • ApacheCassandra0.6.3
      • Cassandra クラスター
    • Eclpseのセッティング
      • stepbystep 実行の設定で結構手間取った。
      Ecplseを適当なディレクトリに展開し起動を行う。
    • Eclpseのセッティング
      EcplseでCassandraのソースを読み込みプロジェクトを作成。
      Cassandraのソースディレクトリを直接指定。
      直接buildを行う為、要注意。Binディレクトリを吹っ飛ばしたり別途ソースを使いまわすことが不可能になります。
    • Eclpseのセッティング
      CassandraのBuild。
      Build.xmlを右クリックし実行タブから外部ツールの構成を選択。
      Targetからbuildとjarを選択
    • Eclpseのセッティング
      Eclipse上部から実行->実行の構成を選択し構成の作成、管理画面を表示
      Cassandraの実行構成の設定
      メインクラスに「org.apache.cassandra.thrift.CassandraDaemon」を指定
    • Eclpseのセッティング
      Cassandraの実行構成の設定
      引き続き引数タブを選択
      引数に
      -Dcom.sun.management.jmxremote.port=8080
      -Dcom.sun.management.jmxremote.ssl=false
      -Dcom.sun.management.jmxremote.authenticate=false
      -Dcassandra
      -Dstorage-config="C:UserskazutakaDownloadsapache-cassandra-0.6.3-srcconf"
      -Dcassandra-foreground=yes
      を設定(少なくとも「Dstorage-config」は必要なようです。
    • Eclpseのセッティング
      CassandraのStepByStep実行
      Debugのパースペクティブを開きデバック実行
    • デーモン起動
      Main関数直後にsetupメソッドがあります。
      public static void main(String[] args)
      {
      CassandraDaemon daemon = new CassandraDaemon();
      String pidFile = System.getProperty("cassandra-pidfile");
      try
      {
      daemon.setup();
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
    • デーモン起動
      Main直後にsetupメソッドがあります。
      public static void main(String[] args)
      {
      CassandraDaemon daemon = new CassandraDaemon();
      String pidFile = System.getProperty("cassandra-pidfile");
      try
      {
      daemon.setup();
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
    • デーモン起動
      Setup内サーバー初期化まで。
      63 private void setup() throws IOException, TTransportException
      64 {
      ~~
      ~~
      69 intlistenPort = DatabaseDescriptor.getThriftPort();
      70 InetAddresslistenAddr = DatabaseDescriptor.getThriftAddress();
      ~~
      ~~
      92 try
      93 {
      94 SystemTable.checkHealth();
      95 }
      ~~
      ~~
      111 CommitLog.recover();
      112 CompactionManager.instance.checkAllColumnFamilies();
      ~~
      ~~
      114 // start server internals
      115 StorageService.instance.initServer();
      ローカルのIPと
      ポートを取得
      システムテーブルのチェック
      Commitログの読み込みと内容のチェック、リカバリーなど
      初期化開始
      ここまでorg.apache.cassandra.thrift.CassandraDaemon
    • デーモン起動
      Setup内サーバー初期化まで。
      63 private void setup() throws IOException, TTransportException
      64 {
      ~~
      ~~
      69 intlistenPort = DatabaseDescriptor.getThriftPort();
      70 InetAddresslistenAddr = DatabaseDescriptor.getThriftAddress();
      ~~
      ~~
      92 try
      93 {
      94 SystemTable.checkHealth();
      95 }
      ~~
      ~~
      111 CommitLog.recover();
      112 CompactionManager.instance.checkAllColumnFamilies();
      ~~
      ~~
      114 // start server internals
      115 StorageService.instance.initServer();
      ローカルのIPと
      ポートを取得
      システムテーブルのチェック
      Commitログの読み込みと内容のチェック、リカバリーなど
      初期化開始
      ここまでorg.apache.cassandra.thrift.CassandraDaemon
    • 相互認知
      org.apache.cassandra.service.StorageService
      initServer
      304 initialized = true;
      305 isClientMode = false;
      306 storageMetadata_ = SystemTable.initMetadata();
      307
      308 // be certain that the recorded clustername matches what the user specified
      309 if (!(Arrays.equals(storageMetadata_.getClusterName(),DatabaseDescriptor.getClusterName().getBytes())))
      310 {
      311 logger_.error("ClusterName mismatch: " + new String(storageMetadata_.getClusterName()) + " != " +
      312 DatabaseDescriptor.getClusterName());
      313 System.exit(3);
      314 }
      315
      316 DatabaseDescriptor.createAllDirectories();
      最初に自分自身の初期化を行う。
      クラスターネーム、キースペース、トークンなどメタ情報取得など
    • ゴシップ開始
      org.apache.cassandra.service.StorageService
      327 logger_.info("Starting up server gossip");
      328
      329 // have to start the gossip service before we can see any info on other nodes. this is necessary
      330 // for bootstrap to get the load info it needs.
      331 // (we won't be part of the storage ring though until we add a nodeId to our state, below.)
      332 Gossiper.instance.register(this);
      333Gossiper.instance.start(FBUtilities.getLocalAddress(), storageMetadata_.getGeneration()); // needed for node-ring gathering.
      「start」の最初にローカルのアドレスを取得。(FBUtilities.getLocalAddress)
      私たちが、他のノードの情報を見ることができる前にゴシップサービスは始めなければなりません。
      これは、「bootstrap」が必要とする負荷の情報を得る為に必要です。
      もっとも、私たちは「nodeid」を私たちのstateに追加するまでストレージ・リングの一部でなくなるでしょう。
    • ゴシップ開始2
      org.apache.cassandra.gms.Gossiper
      838 public void start(InetAddresslocalEndPoint, intgenerationNbr)
      839 {
      840 localEndPoint_ = localEndPoint;
      841 /* Get the seeds from the config and initialize them. */
      842 Set<InetAddress> seedHosts = DatabaseDescriptor.getSeeds();
      843 for (InetAddress seed : seedHosts)
      844 {
      845 if (seed.equals(localEndPoint))
      846 continue;
      847 seeds_.add(seed);
      848 }
      Seedsより自分以外のIPを取得
    • ゴシップ開始3
      org.apache.cassandra.gms.Gossiper
      351 /* initialize the heartbeat state for this localEndPoint */
      352 EndPointStatelocalState = endPointStateMap_.get(localEndPoint_);
      353 if ( localState == null )
      354 {
      355 HeartBeatStatehbState = new HeartBeatState(generationNbr);
      356 localState = new EndPointState(hbState);
      357 localState.isAlive(true);
      358 localState.isAGossiper(true);
      359 endPointStateMap_.put(localEndPoint_, localState);
      360 }
      自分のハートビートステータスを取得
    • ゴシップ開始4
      org.apache.cassandra.gms.Gossiper
      361 /* starts a timer thread */
      362 gossipTimer_.schedule( new GossipTimerTask(), Gossiper.intervalInMillis_, Gossiper.intervalInMillis_);
      GossipTimerTask起動!
        public final static intintervalInMillis_ = 1000;
      というところで1000ミリ秒間隔でタイマー起動
    • GossipTimerTask
      org.apache.cassandra.gms.Gossiper
      private class GossipTimerTask extends TimerTask
      {
      public void run()
      {
      try
      {
      MessagingService.instance.waitUntilListening();
      synchronized( Gossiper.instance )
      {
      endPointStateMap_.get(localEndPoint_).getHeartBeatState().updateHeartBeat();
      List<GossipDigest> gDigests = new ArrayList<GossipDigest>();
      Gossiper.instance.makeRandomGossipDigest(gDigests);
      if ( gDigests.size() > 0 )
      {
      Message message = makeGossipDigestSynMessage(gDigests);
      booleangossipedToSeed = doGossipToLiveMember(message);
      doGossipToUnreachableMember(message);
      if (!gossipedToSeed || liveEndpoints_.size() < seeds_.size())
      doGossipToSeed(message);
      if (logger_.isTraceEnabled())
      logger_.trace("Performing status check ...");
      doStatusCheck();
      }
      }
      }
      catch (Exception e)
      {
      throw new RuntimeException(e);
      }
      }
      }
      GossipTimerTask
      親abstractクラスにてRunnableのインターフェースを実装。
      Runにてスレッド開始
      1000ミリ秒ごとにハートビートを交換。
    • 宣伝
      • 日経Linux8月号に記事書きました。
      検証が大変でした。よかったら見てください。
      ApacheがWorkerだったり、簡易PythonスクリプトをJmeterでたたけるように作っていたり細かい所にネタ満載です。
      質問等有れば連絡ください。
      twitter:railute
      blog:http://www.intheforest.jp/blog/
      e-mail:tomitakazutaka@gmail.com