改写java TreeMap制造方便查询的ip内存库

ip

国库流行的ip库记录数大约在6万条左右,数据格式大约都是如下:
start,end,country...
要查询的时候都是放到mysql里去,然后select * from ip where start>=xx and end end <=xx来得到ip信息,我(54chen)在搞一个实时监控时,因为并发量非常大,全部查询IP库,需要好几万每秒的查询,特改了java的TreeMap的get方法,将所有数据放到内存里来作,put的时候还是保持TreeMap的红黑树实现,以start作为key,而在get的时候有一个 compare的过程,在发现compare是大于0的时候进行如下修改:

else if (cmp > 0) {
int start = ((Data) p.value).getStart();
int end = ((Data) p.value).getEnd();
int intKey = Integer.parseInt(k.toString());
if (intKey >= start && intKey <= end) {
return p;
} p = p.right;
}
大概意思是:在树上遇到比要找的数据小的节点时,从数据中取到end的大小,来参加对比,如果满足要求,直接返回。

附修改好的代码: http://ishare.iask.sina.com.cn/f/15805095.html

重要补充:

由qunar的sunli大侠补充,用实现comparable的key用法更加正宗,代码如下:

public class Chen {
public static void main(String[] args) {

java.util.TreeMap<IpEntry, Data> xmap = new java.util.TreeMap<IpEntry, Data>();
xmap.put(new IpEntry(0, 100), genData(0, 100, ""));
xmap.put(new IpEntry(101, 200), genData(101, 200, "小"));
xmap.put(new IpEntry(2000, 3000), genData(2000, 3000, "佬"));
xmap.put(new IpEntry(201, 300), genData(201, 300, "巴西"));
xmap.put(new IpEntry(501, 600), genData(501, 600, "法国"));
xmap.put(new IpEntry(701, 800), genData(701, 800, "英国"));
xmap.put(new IpEntry(601, 700), genData(601, 700, ""));
xmap.put(new IpEntry(1601, 1700), genData(1601, 1700, "广州"));

Data data = xmap.get(new IpEntry(1260, 1260));
if (data == null) {
System.out.println("not found!");
} else {
System.out.println(data.getCountry());
} }

private static class IpEntry implements Comparable<IpEntry> {

final long start;
final long end;

IpEntry(long start, long end) {
this.start = start;
this.end = end;
}

public int compareTo(IpEntry t) {
long t1 = start - t.start;
if (t1 < 0) {
return -1;
long t2 = end - t.end;
if (t1 >= 0 && t2 <= 0) {
return 0;
return 1;
}

}

private static Data genData(int start, int end, String country) {
Data data = new Data();
data.setCountry(country);
data.setStart(start);
data.setEnd(end);
return data;
} }

Maven打jar包自动生成run脚本-appassembler插件的使用

关键配置:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<programs>
<program>
<mainClass>com.chen.logtailer.Tail</mainClass>
<name>app</name>
</program>
</programs>
</configuration>
</plugin>

#mvn package appassembler:assemble

#sh target/appassembler/bin/app

优点: 不需要管理各种run的脚本,自动生成。

巧用交换机,瞬间切流量

h3c 需求:
1号机服务移到2号机,然后要把1号机搬走。

原理:
交换机有ip对应mac地址的缓存,只需复制到ip和mac,可以在机房内的局域网里瞬间切换到另一个机器上。

作:
1)在2号机准备好1号机的服务,并测试通过。记录1号机的mac和ip
2)以下作要双开窗口,快速作
3)在1号机执行:ifocnfig eth0 down
4)在2号机执行:
ifconfig eth0:0 123.123.123.1
ifconfig eth0:0 hw ether 111111111111[1号机mac]
ifconfig eth0:0 up
5)恭喜成功了!
6)搬走1号机,再也不要回来!
7)在2号机/etc/rc.local里添加:
ifconfig eth0:0 123.123.123.1
ifconfig eth0:0 hw ether 111111111111[1号机mac]
ifconfig eth0:0 up
终。

硬件为王,软件为帝--记突增的访问

mysql 五一归来两周,精力都放在了因为服务器压力突增而来的各种鸡飞狗跳的事情上,今天总结一下,算是对过去两周的总结,希望对各创业团队有所借鉴。
1.访问突增,连锁反应
最先开始出现问题的,是在小负载下没有出现的问题,在大压力时,只要DB一堵,表像就会是循环锁死。
解决之道:
服务要有清晰的架构,开发规范里一定要有明确的架构层次规范,最好还有代码的层次规范。

2.mysql设计不合理,压力指数增加
mysql中存在大量的更新作,特别是大字段或者变长字段的频繁更新,导致磁盘io居高不下,慢查询越来越多。
硬解决之道:
raid卡加电,开启raid写缓存:一般服务器的raid卡都没有开启,开启是有一定用处的,但有一个前提,不是待续的高写入,否则这个写缓存是没有意义的。电池充电时无法缓存,一般三个月充一次电。
转微博:FusionioChina 回复 @YauzZ:多一个故障点。多一份丢数据的可能。而且目前有Raid卡的内存做到1GB。丢不起呀。(5月11日 23:29)
从raid分到多个盘、盘柜,都是从硬件上用多硬盘分担的好方案。

软解决之道:
写方案建立mysql隔离层,在写入前预先处理,类似软件缓存方案,效果明显,修改复杂。

3.后续可做
灵活的中间层数据层切换逻辑,让负载可以随时转移、分隔,基本可以达到“人傻钱多,万事不愁”。