}
}
if fflush {
s.flushOpStats(false)
}
return nil
})
}
3: 针对懒惰删除机制慢,加大低峰期删除key个数和频率,上线后删除过期的key加大10倍,节省内存资源。
func (s *Session) loopWriter(tasks *RequestChan) (err error) {
p := s.Conn.FlushEncoder()
p.MaxInterval = time.Millisecond
p.MaxBuffered = maxPipelineLen / 2
return tasks.PopFrontAll(func(r *Request) error {
resp, err := s.handleResponse®
if err != nil {
resp = redis.NewErrorf(“ERR loopWriter handle response, %s”, err)
if s.Conn!=nil {
log.Errorf(“ERR loopWriter handle response err=%s,remotip=%s”, err.Error() ,s.Conn.RemoteAddr())
}else{
log.Errorf(“ERR loopWriter handle response err=%s”, err.Error())
}
return s.incrOpFails(r, err)
}
fflush := tasks.IsEmpty()
if err := p.Flush(fflush); err != nil {
return s.incrOpFails(r, err)
} else {
s.incrOpStats(r, resp.Type)
cost:= time.Now().UnixNano() - r.UnixNano
if s.config.SessionSlowlogTime > 0 && cost > s.config.SessionSlowlogTime*1000000 {
log.Warnf(“cmd=%s, resType=%s,resLen=%d,cost=%d,forward addr=%s,req key=%s, reqip=%s”,r.OpStr, r.Resp.Type.String(),len(r.Resp.Value),cost/1000000,r.addr,r.key,s.Conn.RemoteAddr())
}
}
if fflush {
s.flushOpStats(false)
}
return nil
})
}
codis-kvrocks
性能数据(第三方数据显示qps可以和redis媲美,耗时较高)
整体架构
问题
- 针对不支持codis增加对codis slot命令支持:
ADD_CMD(“slotsscan”, CommandSlotsScan),
ADD_CMD(“slotsdel”, CommandSlotsDel),
ADD_CMD(“slotsmgrtslot”, CommandSlotsMgrtSlot),
ADD_CMD(“slotsmgrtone”, CommandSlotsMgrtOne),
ADD_CMD(“slotsmgrttagslot”, CommandSlotsMgrtTagSlot),
ADD_CMD(“slotsmgrttagone”, CommandSlotsMgrtTagOne),
ADD_CMD(“slotsrestore”, CommandSlotsRestore),
ADD_CMD(“slotshashkey”, CommandSlotsHashKey),
ADD_CMD(“slotscheck”, CommandSlotsCheck),
ADD_CMD(“slotsmgrtslot-async”, CommandSlotsMgrtSlotAsync),
ADD_CMD(“slotsmgrttagslot-async”, CommandSlotsMgrtTagSlotAsync),
ADD_CMD(“slotsmgrt-exec-wrapper”, CommandSlotsMgrtExecWrapper),
ADD_CMD(“slotsmgrt-async-status”, CommandSlotsMgrtAsyncStatus),
ADD_CMD(“slotsmgrt-async-cancel”, CommandSlotsMgrtAsyncCancel),
如果codis扩容实例需要迁移slot中keys代码如下:
void SlotsMgrtSenderThread::loop() {
Redis::Slot slot_db(storage_);
while (!IsStopped()) {
auto s = Util::SockConnect(dest_ip_, dest_port_, &sock_fd, timeout_ms_, timeout_ms_);
moved_keys_all_ = 0;
while (is_migrating_) {
if (keys_num_ <= 0) {
sleep(1);
continue;
}
std::vectorstd::string migrate_batch_keys;
auto s = ElectMigrateKeys(&migrate_batch_keys);
std::lock_guardstd::mutex ones_guard(ones_mu_);
std::copy(migrating_ones_.begin(), migrating_ones_.end(), std::back_inserter(migrate_batch_keys));
if (migrate_batch_keys.size() != 0) {
moved_keys_num_ = 0;
}
std::vectorstd::string().swap(migrating_ones_);
for (auto const &key : migrate_batch_keys) {
auto s = slot_db.MigrateOneKey(sock_fd, key);
moved_keys_num_++;
moved_keys_all_++;
remained_keys_num_–;
}
if (error_) {
break;
}
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
,可以添加下面V无偿领取!(备注Java)**
[外链图片转存中…(img-96EkSmBE-1711104058916)]
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
[外链图片转存中…(img-LLcLlKAk-1711104058916)]