// Update when zk updates func (d *Dispatcher) Update(group map[int][]string, store map[string]*meta.Store, volume map[int32]*meta.VolumeState, storeVolume map[string][]int32) (err error) { var ( gid int i int vid int32 gids []int sid string stores []string restSpace, minScore, score int totalAdd, totalAddDelay uint64 write, ok bool storeMeta *meta.Store volumeState *meta.VolumeState ) gids = []int{} for gid, stores = range group { write = true // check all stores can writeable by the group. for _, sid = range stores { if storeMeta, ok = store[sid]; !ok { log.Errorf("idStore cannot match store: %s", sid) break } if !storeMeta.CanWrite() { write = false break } } if !write { continue } // calc score for _, sid = range stores { totalAdd, totalAddDelay, restSpace, minScore = 0, 0, 0, 0 // get all volumes by the store. for _, vid = range storeVolume[sid] { volumeState = volume[vid] totalAdd = totalAdd + volumeState.TotalWriteProcessed restSpace = restSpace + int(volumeState.FreeSpace) totalAddDelay = totalAddDelay + volumeState.TotalWriteDelay } score = d.calScore(int(totalAdd), int(totalAddDelay), restSpace) if score < minScore || minScore == 0 { minScore = score } } for i = 0; i < minScore; i++ { gids = append(gids, gid) } } d.gids = gids return }
// checkNeedles check the store health. func (p *Pitchfork) checkNeedles(store *meta.Store, stop chan struct{}) (err error) { var ( status, i int needle *meta.Needle volume *meta.Volume volumes []*meta.Volume ) log.Infof("checkNeedles job start") for { select { case <-stop: log.Infof("checkNeedles job stop") return case <-time.After(p.config.HeadInterval): break } if volumes, err = store.Info(); err != nil { log.Errorf("get store info failed, retry host:%s", store.Stat) continue } status = store.Status for _, volume = range volumes { if volume.Block.LastErr != nil { break } else { for _, needle = range volume.CheckNeedles { for i = 0; i < retryCount; i++ { if err = store.Head(needle, volume.Id); err == nil { break } } if err != nil { log.Errorf("head store failed, needle:%d host:%s", needle.Key, store.Stat) store.Status = meta.StoreStatusFail goto feedback } } } } feedback: if status != store.Status { if err = p.zk.SetStore(store); err != nil { log.Errorf("update store zk status failed, retry") continue } if err = p.zk.setRoot(); err != nil { log.Errorf("setRoot zk failed") } } } return }
// checkHealth check the store health. func (p *Pitchfork) checkHealth(store *meta.Store, stop chan struct{}) (err error) { var ( status, i int volume *meta.Volume volumes []*meta.Volume ) log.Infof("check_health job start") for { select { case <-stop: log.Infof("check_health job stop") return case <-time.After(p.config.GetInterval): break } status = store.Status for i = 0; i < retryCount; i++ { if volumes, err = store.Info(); err == nil { break } } if err == nil { for _, volume = range volumes { if volume.Block.LastErr != nil { log.Infof("get store block.lastErr:%s host:%s", volume.Block.LastErr, store.Stat) store.Status = meta.StoreStatusFail break } else if volume.Block.Full() { log.Infof("block: %s, offset: %d", volume.Block.File, volume.Block.Offset) store.Status = meta.StoreStatusRead } } } else { log.Errorf("get store info failed, retry host:%s", store.Stat) store.Status = meta.StoreStatusFail } if status != store.Status { if err = p.zk.SetStore(store); err != nil { log.Errorf("update store zk status failed, retry") continue } if err = p.zk.setRoot(); err != nil { log.Errorf("setRoot zk failed") } } } return }
// DelStores get delable stores for http del func (d *Directory) DelStores(key int64, cookie int32) (vid int32, stores []string, err error) { var ( n *meta.Needle ok bool store string svrs []string storeMeta *meta.Store ) if n, err = d.hbase.Get(key); err != nil { log.Errorf("hbase.Get error(%v)", err) err = errors.ErrHbase return } if n == nil { err = errors.ErrNeedleNotExist return } if n.Cookie != cookie { err = errors.ErrNeedleCookie return } vid = n.Vid if svrs, ok = d.volumeStore[n.Vid]; !ok { err = errors.ErrZookeeperDataError return } stores = make([]string, 0, len(svrs)) for _, store = range svrs { if storeMeta, ok = d.store[store]; !ok { err = errors.ErrZookeeperDataError return } if !storeMeta.CanWrite() { err = errors.ErrStoreNotAvailable return } stores = append(stores, storeMeta.Api) } if err = d.hbase.Del(key); err != nil { log.Errorf("hbase.Del error(%v)", err) err = errors.ErrHbase } return }