Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便 .
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
以下为使用Redis计数来实现的根据IP设置黑名单的简单小例子
配置文件:
<span style="font-family:SimSun;font-size:14px;"> <bean id="redisDao" class="com.dao.RedisDao" scope="prototype">
<property name="shardedJedisPool">
<ref bean="shardedJedisPool"/>
</property>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxActive}" /> <!--最大连接数-->
<property name="maxIdle" value="${redis.maxIdle}" /> <!--最大空闲数-->
<property name="maxWaitMillis" value="${redis.maxWait}" /> <!--最大等待时间ms-->
<property name="testOnBorrow" value="true" />
</bean>
<bean id="jedis.shardInfo" class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.host}" />
<constructor-arg index="1" value="${redis.port}" />
</bean>
<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1">
<list>
<ref bean="jedis.shardInfo" />
</list>
</constructor-arg>
</bean></span>
Dao文件:
<span style="font-family:SimSun;font-size:14px;">import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
public class RedisDao {
private static final Logger logger = Logger.getLogger(RedisDao.class);
@Autowired
private ShardedJedisPool shardedJedisPool;
public void set(String key, String value) {
ShardedJedis jedis = shardedJedisPool.getResource();
try {
jedis.set(key, value);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return;
}
public void rpush(String key, String value1, String value2, String value3, String value4) {
ShardedJedis jedis = shardedJedisPool.getResource();
try {
jedis.rpush(key, value1, value2, value3, value4);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return;
}
public String get(String key) {
ShardedJedis jedis = shardedJedisPool.getResource();
String result = "";
try {
result = jedis.get(key);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
public Long hset(String key, String field, String value) {
ShardedJedis jedis = shardedJedisPool.getResource();
Long result = null;
try {
result = jedis.hset(key, field, value);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
public String hget(String key, String field) {
ShardedJedis jedis = shardedJedisPool.getResource();
String result = null;
try {
result = jedis.hget(key, field);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
public List<String> lrange(String key,long start,long end) {
ShardedJedis jedis = shardedJedisPool.getResource();
List<String> result = null;
try {
result = jedis.lrange(key, start, end);;
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
public Long del(String key) {
ShardedJedis jedis = shardedJedisPool.getResource();
Long result = null;
try {
result = jedis.del(key);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
/**
* 添加key value 并且设置存活时间
* @param key
* @param value
* @param liveTime
*/
public void set(String key,String value,int liveTime){
ShardedJedis jedis = shardedJedisPool.getResource();
try {
this.set(key, value);
jedis.expire(key, liveTime);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
}
/**
* 检查key是否已经存在
* @param key
* @return
*/
public boolean exists(String key){
ShardedJedis jedis = shardedJedisPool.getResource();
boolean result =false;
try {
result=jedis.exists(key);
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result;
}
/**
* 获取一个key的模糊匹配总数
* @param key
* @return
*/
public int getKeyCount(String key) {
ShardedJedis jedis = shardedJedisPool.getResource();
Set<String> result = null;
try {
result = jedis.getShard(key).keys(key + "*");
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result.size();
}
/**
* 查看redis里有多少数据
*/
public long dbSize(){
ShardedJedis jedis = shardedJedisPool.getResource();
Set<String> result = null;
try {
} catch (Exception e) {
logger.error(e.getMessage(), e);
shardedJedisPool.returnBrokenResource(jedis);
} finally {
shardedJedisPool.returnResource(jedis);
}
return result.size();
}
public ShardedJedisPool getShardedJedisPool() {
return shardedJedisPool;
}
public void setShardedJedisPool(ShardedJedisPool shardedJedisPool) {
this.shardedJedisPool = shardedJedisPool;
}
}
</span>
Service处理:
<span style="font-family:SimSun;font-size:14px;">protected boolean validateIp(String Ip){
if(null == redisDao){
redisDao = (RedisDao) SpringApplicationContextHolder.context.getBean("redisDao");
}
//取到数据后放入ip库,并设置30s后失效
redisDao.set(Ip+"_"+Walk.run(), Ip, 30);
//获取当前库中该IP的总数
int count=redisDao.getKeyCount(Ip+"_");
System.out.println(Ip+"=========count"+count);
//如果大于90条
if(count>=90){
//放入黑名单,设置12h后失效
redisDao.set(Ip,new Date().toString(), 43200);
return false;
}else if(StringUtils.isNotBlank(redisDao.get(Ip))){
//验证ip是否在黑名单里
//如果在,不与处理
return false;
}
//如果不在,进行后续处理
return true;
}</span>