Gossip事始め

  • 2,345 views
Uploaded on

第八回cassandra勉強会slideです。

第八回cassandra勉強会slideです。

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,345
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
6
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Gossip事始め
    株式会社ムロドー
    とみたかずたか
  • 2. アジェンダ
    Gossip事始め
    コードリーディングの準備
    デーモン起動
    起動準備
    デーモン初期化
    Gossip開始
  • 3. コードリーディング下準備
    • Eclpseでstepbystep 実行を行う。
    用意するもの
    • 面倒くさいのでpleiadesonGlileo を用意
    • 4. ApacheCassandra0.6.3
    • 5. Cassandra クラスター
  • Eclpseのセッティング
    • stepbystep 実行の設定で結構手間取った。
    Ecplseを適当なディレクトリに展開し起動を行う。
  • 6. Eclpseのセッティング
    EcplseでCassandraのソースを読み込みプロジェクトを作成。
    Cassandraのソースディレクトリを直接指定。
    直接buildを行う為、要注意。Binディレクトリを吹っ飛ばしたり別途ソースを使いまわすことが不可能になります。
  • 7. Eclpseのセッティング
    CassandraのBuild。
    Build.xmlを右クリックし実行タブから外部ツールの構成を選択。
    Targetからbuildとjarを選択
  • 8. Eclpseのセッティング
    Eclipse上部から実行->実行の構成を選択し構成の作成、管理画面を表示
    Cassandraの実行構成の設定
    メインクラスに「org.apache.cassandra.thrift.CassandraDaemon」を指定
  • 9. 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」は必要なようです。
  • 10. Eclpseのセッティング
    CassandraのStepByStep実行
    Debugのパースペクティブを開きデバック実行
  • 11. デーモン起動
    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
  • 12. デーモン起動
    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
  • 13. デーモン起動
    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
  • 14. デーモン起動
    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
  • 15. 相互認知
    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();
    最初に自分自身の初期化を行う。
    クラスターネーム、キースペース、トークンなどメタ情報取得など
  • 16. ゴシップ開始
    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に追加するまでストレージ・リングの一部でなくなるでしょう。
  • 17. ゴシップ開始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を取得
  • 18. ゴシップ開始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 }
    自分のハートビートステータスを取得
  • 19. ゴシップ開始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ミリ秒間隔でタイマー起動
  • 20. 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ミリ秒ごとにハートビートを交換。
  • 21. 宣伝
    • 日経Linux8月号に記事書きました。
    検証が大変でした。よかったら見てください。
    ApacheがWorkerだったり、簡易PythonスクリプトをJmeterでたたけるように作っていたり細かい所にネタ満載です。
    質問等有れば連絡ください。
    twitter:railute
    blog:http://www.intheforest.jp/blog/
    e-mail:tomitakazutaka@gmail.com