|
需求:现需要一redis可视化管理工具,能进行大数据量(10w以上)的查询,修改。
现调研结果如下:
目前主流redis管理工具有 phpRedisAdmin(php) redisAdminUI(.net),基本界面如下所示:
可设置List,HashMap型同一个key值的分页功能,但是左栏keys无分页功能,当数据量达到十万级别,基本就死掉了。
查看了源码,发现jedis并没有分页的支持功能,现处理方式:
public ModelAndView list(HttpServletRequest request, @RequestParam(required = false) String ckey, @RequestParam(required = false) String pageNum, @RequestParam(required = false) String numPerPage) {
// 从池中获取一个Jedis对象
ModelMap modelMap = new ModelMap();
String db = request.getParameter("db");
String bkey = request.getParameter("bkey");
pageNum = (pageNum == null) || "".equals(pageNum) ? "1" : pageNum;
Integer pn = Integer.parseInt(pageNum);
numPerPage = (numPerPage == null) || "".equals(numPerPage) ? "18" : numPerPage;
Integer pz = Integer.parseInt(numPerPage);
db = (db == null) || "".equals(db) ? "0" : db;
Jedis jedis = JedisUtil.getJedis(Integer.parseInt(db));
String newKey = ckey != null && ckey.length() > 0 ? bkey + ckey : bkey + "*";
int total = jedis.keys(newKey).size();
Set<String> set = jedis.keys(newKey);
List<String> list = new ArrayList<String>(set);
Collections.sort(list);
Map resultMap = new TreeMap<String, String>();
if (list.size() > 0) {
int start = (pn - 1) * pz;
int end = pn * pz > list.size() ? list.size() : pn * pz;
Pipeline pip = jedis.pipelined();
for (int i = start; i < end; i++) {
pip.get(list.get(i));
}
List<Object> result = pip.syncAndReturnAll();
for (int i = start; i < start + result.size(); i++) {
resultMap.put(list.get(i), (String) result.get(i - start));
}
}
// 释放对象池
JedisUtil.closeJedis(jedis);
if (ckey != null) {
modelMap.put("ckey", ckey);
}
modelMap.put("bkey", bkey);
modelMap.put("db", db);
modelMap.put("total", total);
modelMap.put("resultMap", resultMap);
modelMap.put("pageCount", (int) Math.ceil(total / pz.doubleValue()));
modelMap.put("pageNum", pn);
modelMap.put("numPerPage", pz);
return new ModelAndView("/redis/list", modelMap);
}
虽然牺牲了该模块的内存,但对redis性能影响较小,经测试20w数据下,phpRedisAdmin已经白屏,但该模块速度在2s内。
界面如下,目前正实现根据不同前缀分业务的配置功能:
key值检索支持pattern匹配。
另:用前缀区分业务类型而未使用db,因为虽然说Redis支持多个数据库(默认32个,可以配置更多),但是除了默认的0号库以外,其它的都需要通过一个额外请求才能使用。所以用前缀作为命名空间可能会更明智一点。另外,在使用前缀作为命名空间区隔不同key的时候,最好在程序中使用全局配置来实现,直接在代码里写前缀的做法要严格避免,这样可维护性实在太差了。
版权声明:本文为博主原创文章,未经博主允许不得转载。 |
|
|