ceph源码分析--Monitor对osd report进行报down处理

本文详细解析了Ceph Monitor中的tick处理流程,包括如何通过PGMonitor的tick函数处理OSD报告的超时情况,以及如何清除过期的数据增量。同时,介绍了在作为集群领导者时,Monitor如何检查OSD的状态并标记离线节点。

上一篇讲到Monitor的tick处理,顺带讲解Monitor对osd report超时的处理
该部分在PGMonitor的tick中调用

void Monitor::tick()
{
  // ok go.
  dout(11) << "tick" << dendl;
  ···
  //调用paxosservice的tick()
  for (vector<PaxosService*>::iterator p = paxos_service.begin(); p != paxos_service.end(); ++p) {
    (*p)->tick();
    (*p)->maybe_trim();
  }

  ···
  new_tick();
}

在这里调用了PGMonitor的tick()

void PGMonitor::tick()
{
  if (!is_active()) return;
  if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) {
    return;
  }
  //处理osdreport超时
  handle_osd_timeouts();

  if (!pg_map.pg_sum_deltas.empty()) {
    utime_t age = ceph_clock_now() - pg_map.stamp;
    if (age > 2 * g_conf->mon_delta_reset_interval) {
      dout(10) << " clearing pg_map delta (" << age << " > " << g_conf->mon_delta_reset_interval << " seconds old)" << dendl;
      pg_map.clear_delta();
    }
  }

  /* If we have deltas for pools, run through pgmap's 'per_pool_sum_delta' and
   * clear any deltas that are old enough.
   *
   * Note that 'per_pool_sum_delta' keeps a pool id as key, and a pair containing
   * the calc'ed stats delta and an absolute timestamp from when those stats were
   * obtained -- the timestamp IS NOT a delta itself.
   */
  if (!pg_map.per_pool_sum_deltas.empty()) {
    ceph::unordered_map<uint64_t,pair<pool_stat_t,utime_t> >::iterator it;
    for (it = pg_map.per_pool_sum_delta.begin();
         it != pg_map.per_pool_sum_delta.end(); ) {
      utime_t age = ceph_clock_now() - it->second.second;
      if (age > 2*g_conf->mon_delta_reset_interval) {
    dout(10) << " clearing pg_map delta for pool " << it->first
             << " (" << age << " > " << g_conf->mon_delta_reset_interval
             << " seconds old)" << dendl;
    pg_map.per_pool_sum_deltas.erase(it->first);
    pg_map.per_pool_sum_deltas_stamps.erase(it->first);
    pg_map.per_pool_sum_delta.erase((it++)->first);
      } else {
    ++it;
      }
    }
  }

  dout(10) << pg_map << dendl;
}

调用了void PGMonitor::handle_osd_timeouts()

void PGMonitor::handle_osd_timeouts()
{
  if (!mon->is_leader())
    return;
  if (did_delete)
    return;

  utime_t now(ceph_clock_now());
  utime_t timeo(g_conf->mon_osd_report_timeout, 0);
  if (now - mon->get_leader_since() < timeo) {
    // We haven't been the leader for long enough to consider OSD timeouts
    //
    return;
  }

  if (mon->osdmon()->is_writeable())
  //调用了osdmon的handle_osd_timeouts
    mon->osdmon()->handle_osd_timeouts(now, last_osd_report);
}

bool OSDMonitor::handle_osd_timeouts(const utime_t &now,std::map

bool OSDMonitor::handle_osd_timeouts(const utime_t &now,
                     std::map<int,utime_t> &last_osd_report)
{
  utime_t timeo(g_conf->mon_osd_report_timeout, 0);
  if (now - mon->get_leader_since() < timeo) {
    // We haven't been the leader for long enough to consider OSD timeouts
    return false;
  }

  int max_osd = osdmap.get_max_osd();
  bool new_down = false;

  for (int i=0; i < max_osd; ++i) {
    dout(30) << __func__ << ": checking up on osd " << i << dendl;
    if (!osdmap.exists(i)) {
      last_osd_report.erase(i); // if any
      continue;
    }
    if (!osdmap.is_up(i))
      continue;
    const std::map<int,utime_t>::const_iterator t = last_osd_report.find(i);
    if (t == last_osd_report.end()) {
      // it wasn't in the map; start the timer.
      last_osd_report[i] = now;
    } else if (can_mark_down(i)) {
      utime_t diff = now - t->second;
      if (diff > timeo) {
    mon->clog->info() << "osd." << i << " marked down after no beacon for "
              << diff << " seconds";
    derr << "no beacon from osd." << i << " since " << t->second
         << ", " << diff << " seconds ago.  marking down" << dendl;
    pending_inc.new_state[i] = CEPH_OSD_UP;
    new_down = true;
      }
    }
  }
  return new_down;
}
### Ceph OSD 中 `ceph-osd --mkjournal` 的使用方法及作用 #### 1. 命令概述 `ceph-osd --mkjournal` 是 Ceph 提供的一个工具,用于初始化或重新创建一个指定 OSD 的 journal 文件。Journal 是 Ceph OSD 数据持久化的关键组件之一,主要用于记录元数据变更的历史日志,从而加速写入操作并提高系统的可靠性[^1]。 #### 2. 使用场景 该命令通常在以下情况下使用: - 修改现有 OSD 的 journal 大小。 - 更改 journal 的存储位置(例如从本地文件迁移到专用 SSD 分区)。 - 初始化新的 OSD 或修复损坏的 journal 文件。 #### 3. 参数说明 执行 `ceph-osd --mkjournal` 时,需要指定目标 OSD 的 ID (`-i`)。以下是完整的命令结构及其参数解释: ```bash ceph-osd -i <osd_id> --mkjournal ``` | 参数 | 描述 | |------------|----------------------------------------------------------------------| | `-i <osd_id>` | 指定目标 OSD 的唯一标识符,通常是整数形式,例如 `0`, `1`, 等等。 | #### 4. 实际应用案例 ##### (1)修改 Journal 大小 如果希望更改已存在的 OSD 的 journal 大小而不需完全重建整个 OSD,则可以按照如下步骤操作: 1. **停止目标 OSD** 关闭对应的目标 OSD 服务以防止数据丢失或混乱。 ```bash systemctl stop ceph-osd@<osd_id>.service ``` 2. **删除旧的 Journal 文件** 移除当前的 journal 文件。 ```bash rm /var/lib/ceph/osd/ceph-<osd_id>/journal ``` 3. **设置新的 Journal 大小** 编辑配置文件 `/etc/ceph/ceph.conf`,将 `osd_journal_size` 设置为目标大小(单位为 MB)。例如: ```ini osd_journal_size = 10240 ``` 4. **重新创建 Journal** 使用 `--mkjournal` 参数重新生成 journal 文件。 ```bash ceph-osd -i <osd_id> --mkjournal ``` 5. **重启 OSD 服务** 启动 OSD 并验证 journal 是否正常工作。 ```bash systemctl start ceph-osd@<osd_id>.service ls -lh /var/lib/ceph/osd/ceph-<osd_id>/journal ``` ##### (2)迁移 Journal 至独立分区 当需要将 journal 移动到单独的高性能 SSD 分区时,可按以下流程操作: 1. **停止目标 OSD** ```bash systemctl stop ceph-osd@<osd_id>.service ``` 2. **刷新 Journal 数据** 确保所有未提交的日志都已同步到主存储中。 ```bash ceph-osd --flush-journal -i <osd_id> ``` 3. **移除原有 Journal 链接** 删除现有的 journal 符号链接。 ```bash rm /var/lib/ceph/osd/ceph-<osd_id>/journal ``` 4. **创建指向新分区的符号链接** 假设新分区位于 `/dev/sdb1`,则可以通过以下命令完成替换: ```bash ln -s /dev/sdb1 /var/lib/ceph/osd/ceph-<osd_id>/journal ``` 5. **重新初始化 Journal** 利用 `--mkjournal` 参数更新 journal 元数据。 ```bash ceph-osd -i <osd_id> --mkjournal ``` 6. **启动 OSD 服务** 最后恢复 OSD 正常运行状态。 ```bash systemctl start ceph-osd@<osd_id>.service ``` #### 5. 注意事项 - 在线上的生产环境中进行任何涉及 journal 的改动之前,请务必做好充分备份,并确认集群处于健康状态。 - 如果计划调整 journal 的存储介质类型(如从 HDD 转向 SSD),应提前规划好分区布局并合理分配资源[^2]。 - 当前版本可能对某些功能有所限制;因此建议始终查阅官方文档获取最新指导信息[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值