Beispiel #1
0
func cmdDashboard(argv []string) (err error) {
	usage := `usage: codis-config dashboard [--addr=<address>] [--http-log=<log_file>]

options:
	--addr	listen ip:port, e.g. localhost:12345, :8086, [default: :8086]
	--http-log	http request log [default: request.log ]
`

	args, err := docopt.Parse(usage, argv, true, "", false)
	if err != nil {
		log.ErrorErrorf(err, "parse args failed")
		return err
	}
	log.Debugf("parse args = {%+v}", args)

	logFileName := "request.log"
	if args["--http-log"] != nil {
		logFileName = args["--http-log"].(string)
	}

	addr := ":8086"
	if args["--addr"] != nil {
		addr = args["--addr"].(string)
	}

	runDashboard(addr, logFileName)
	return nil
}
Beispiel #2
0
func cmdProxy(argv []string) (err error) {
	usage := `usage:
	codis-config proxy list
	codis-config proxy offline <proxy_name>
	codis-config proxy online <proxy_name>
`
	args, err := docopt.Parse(usage, argv, true, "", false)
	if err != nil {
		log.ErrorErrorf(err, "parse args failed")
		return err
	}
	log.Debugf("parse args = {%+v}", args)

	if args["list"].(bool) {
		return runProxyList()
	}

	proxyName := args["<proxy_name>"].(string)
	if args["online"].(bool) {
		return runSetProxyStatus(proxyName, models.PROXY_STATE_ONLINE)
	}
	if args["offline"].(bool) {
		return runSetProxyStatus(proxyName, models.PROXY_STATE_MARK_OFFLINE)
	}
	return nil
}
Beispiel #3
0
func (s *Router) fillSlot(i int, addr, from string, lock bool) {
	if !s.isValidSlot(i) {
		return
	}
	slot := s.slots[i]
	slot.blockAndWait()

	s.putBackendConn(slot.backend.bc)
	s.putBackendConn(slot.migrate.bc)
	slot.reset()

	if len(addr) != 0 {
		xx := strings.Split(addr, ":")
		if len(xx) >= 1 {
			slot.backend.host = []byte(xx[0])
		}
		if len(xx) >= 2 {
			slot.backend.port = []byte(xx[1])
		}
		slot.backend.addr = addr
		slot.backend.bc = s.getBackendConn(addr)
	}
	if len(from) != 0 {
		slot.migrate.from = from
		slot.migrate.bc = s.getBackendConn(from)
	}

	if !lock {
		slot.unblock()
	}

	if slot.migrate.bc != nil {
		log.Debugf("fill slot %04d, backend.addr = %s, migrate.from = %s",
			i, slot.backend.addr, slot.migrate.from)
	} else {
		log.Debugf("fill slot %04d, backend.addr = %s",
			i, slot.backend.addr)
	}
}
Beispiel #4
0
func cmdServer(argv []string) (err error) {
	usage := `usage:
	codis-config server list
	codis-config server add <group_id> <redis_addr> <role>
	codis-config server remove <group_id> <redis_addr>
	codis-config server promote <group_id> <redis_addr>
	codis-config server add-group <group_id>
	codis-config server remove-group <group_id>
`
	args, err := docopt.Parse(usage, argv, true, "", false)
	if err != nil {
		log.ErrorErrorf(err, "parse args failed")
		return err
	}
	log.Debugf("parse args = {%+v}", args)

	if args["list"].(bool) {
		return runListServerGroup()
	}

	groupId, err := strconv.Atoi(args["<group_id>"].(string))
	if err != nil {
		log.ErrorErrorf(err, "parse <group_id> failed")
		return err
	}

	if args["remove-group"].(bool) {
		return runRemoveServerGroup(groupId)
	}
	if args["add-group"].(bool) {
		return runAddServerGroup(groupId)
	}

	serverAddr := args["<redis_addr>"].(string)
	if args["add"].(bool) {
		role := args["<role>"].(string)
		return runAddServerToGroup(groupId, serverAddr, role)
	}
	if args["remove"].(bool) {
		return runRemoveServerFromGroup(groupId, serverAddr)
	}
	if args["promote"].(bool) {
		return runPromoteServerToMaster(groupId, serverAddr)
	}

	return nil
}
Beispiel #5
0
func cmdAction(argv []string) (err error) {
	usage := `usage: codis-config action (gc [-n <num> | -s <seconds>] | remove-lock | remove-fence)

options:
	gc:
	gc -n N		keep last N actions;
	gc -s Sec	keep last Sec seconds actions;

	remove-lock	force remove zookeeper lock;
`
	args, err := docopt.Parse(usage, argv, true, "", false)
	if err != nil {
		log.ErrorErrorf(err, "parse args failed")
		return errors.Trace(err)
	}
	log.Debugf("parse args = {%+v}", args)

	if args["remove-lock"].(bool) {
		return errors.Trace(runRemoveLock())
	}

	if args["remove-fence"].(bool) {
		return errors.Trace(runRemoveFence())
	}

	if args["gc"].(bool) {
		if args["-n"].(bool) {
			n, err := strconv.Atoi(args["<num>"].(string))
			if err != nil {
				log.ErrorErrorf(err, "parse <num> failed")
				return err
			}
			return runGCKeepN(n)
		} else if args["-s"].(bool) {
			sec, err := strconv.Atoi(args["<seconds>"].(string))
			if err != nil {
				log.ErrorErrorf(err, "parse <seconds> failed")
				return errors.Trace(err)
			}
			return runGCKeepNSec(sec)
		}
	}

	return nil
}
Beispiel #6
0
func (top *Topology) GetSlotByIndex(i int) (*models.Slot, *models.ServerGroup, error) {
	slot, err := models.GetSlot(top.zkConn, top.ProductName, i)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}

	log.Debugf("get slot %d : %+v", i, slot)
	if slot.State.Status != models.SLOT_STATUS_ONLINE && slot.State.Status != models.SLOT_STATUS_MIGRATE {
		log.Errorf("slot not online, %+v", slot)
	}

	groupServer, err := models.GetGroup(top.zkConn, top.ProductName, slot.GroupId)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}

	return slot, groupServer, nil
}
Beispiel #7
0
func (s *Slot) slotsmgrt(r *Request, key []byte) error {
	if len(key) == 0 || s.migrate.bc == nil {
		return nil
	}
	m := &Request{
		Owner: r.Owner,
		Wait:  &sync.WaitGroup{},
		Resp: redis.NewArray([]*redis.Resp{
			redis.NewBulkBytes([]byte("SLOTSMGRTTAGONE")),
			redis.NewBulkBytes(s.backend.host),
			redis.NewBulkBytes(s.backend.port),
			redis.NewBulkBytes([]byte("3000")),
			redis.NewBulkBytes(key),
		}),
	}
	m.Wait.Add(1)

	s.migrate.bc.PushBack(m)

	m.Wait.Wait()

	resp, err := m.Response.Resp, m.Response.Err
	if err != nil {
		return err
	}
	if resp == nil {
		return ErrRespIsRequired
	}
	if resp.IsError() {
		return errors.New(fmt.Sprintf("error resp: %s", resp.Value))
	}
	if resp.IsInt() {
		log.Debugf("slot-%04d migrate from %s to %s: key = %s, resp = %s",
			s.Id, s.migrate.from, s.backend.addr, key, resp.Value)
		return nil
	} else {
		return errors.New(fmt.Sprintf("error resp: should be integer, but got %s", resp.Type))
	}
}
Beispiel #8
0
func cmdSlot(argv []string) (err error) {
	usage := `usage:
	codis-config slot init [-f]
	codis-config slot info <slot_id>
	codis-config slot set <slot_id> <group_id> <status>
	codis-config slot range-set <slot_from> <slot_to> <group_id> <status>
	codis-config slot migrate <slot_from> <slot_to> <group_id> [--delay=<delay_time_in_ms>]
	codis-config slot rebalance [--delay=<delay_time_in_ms>]
`

	args, err := docopt.Parse(usage, argv, true, "", false)
	if err != nil {
		log.ErrorErrorf(err, "parse args failed")
		return errors.Trace(err)
	}
	log.Debugf("parse args = {%+v}", args)

	// no need to lock here
	// locked in runmigratetask
	if args["migrate"].(bool) {
		delay := 0
		groupId, err := strconv.Atoi(args["<group_id>"].(string))
		if args["--delay"] != nil {
			delay, err = strconv.Atoi(args["--delay"].(string))
			if err != nil {
				log.ErrorErrorf(err, "parse <group_id> failed")
				return errors.Trace(err)
			}
		}
		slotFrom, err := strconv.Atoi(args["<slot_from>"].(string))
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_from> failed")
			return errors.Trace(err)
		}

		slotTo, err := strconv.Atoi(args["<slot_to>"].(string))
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_to> failed")
			return errors.Trace(err)
		}
		return runSlotMigrate(slotFrom, slotTo, groupId, delay)
	}
	if args["rebalance"].(bool) {
		delay := 0
		if args["--delay"] != nil {
			delay, err = strconv.Atoi(args["--delay"].(string))
			if err != nil {
				log.ErrorErrorf(err, "parse <delay> failed")
				return errors.Trace(err)
			}
		}
		return runRebalance(delay)
	}

	if args["init"].(bool) {
		force := args["-f"].(bool)
		return runSlotInit(force)
	}

	if args["info"].(bool) {
		slotId, err := strconv.Atoi(args["<slot_id>"].(string))
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_id> failed")
			return errors.Trace(err)
		}
		return runSlotInfo(slotId)
	}

	groupId, err := strconv.Atoi(args["<group_id>"].(string))
	if err != nil {
		log.ErrorErrorf(err, "parse <group_id> failed")
		return errors.Trace(err)
	}

	if args["set"].(bool) {
		slotId, err := strconv.Atoi(args["<slot_id>"].(string))
		status := args["<status>"].(string)
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_id> failed")
			return errors.Trace(err)
		}
		return runSlotSet(slotId, groupId, status)
	}

	if args["range-set"].(bool) {
		status := args["<status>"].(string)
		slotFrom, err := strconv.Atoi(args["<slot_from>"].(string))
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_from> failed")
			return errors.Trace(err)
		}
		slotTo, err := strconv.Atoi(args["<slot_to>"].(string))
		if err != nil {
			log.ErrorErrorf(err, "parse <slot_to> failed")
			return errors.Trace(err)
		}
		return errors.Trace(runSlotRangeSet(slotFrom, slotTo, groupId, status))
	}
	return nil
}