redis定义:
1.redis是什么?
redis是一个高性能的key-value数据库,支持存储的value类型包括string,list,set,zset和hash,并且都支持push/pop add/remove及取交集并集和差集等操作。
2.redis的特点:
- 数据都缓存在内存中,会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。
- 以集群方式部署,主服务器进行对外服务,支持主从同步,数据可以从主服务器向任意数量的从服务器进行同步,支持级联架构。
- 实现了发布/订阅机制 ,数据是分频道存储的(在不同的channel),消费数据的前提要订阅channel。
- edis中值得类型不仅限于字符串,但由字符串组成,还支持:
3.redis架构: - 无中心架构,节点之间互为主从
- 根据hash算法映射key值和其存储的主节点的位置,各节点维护key和server之间的映射关系
- client可以向任意节点发起请求,无所谓主从,如果server就是client要找的节点,就会回应,如果不是,只会重定向client
- 如果在client请求和重定向请求之间,拓扑发生改变,则下一次重定向请求会被再次重定向,直到找到正确的server
- 但目前fusionInsight HD中的redis集群只支持一主一从模式
4.应用场景:
获取最新消息
排行榜应用
计数器应用
符合:高性能 低延迟 丰富数据结构存取 支持持久化
5.实现商品推荐系统:
方案:
引入redis,降低从数据库和文件系统读取数据的次数;
将结果缓存到redis,实现及读及取;相对于HBase更快,因为HBase虽然由索引但仍然要去访问底层的文件系统
结构设计:
由于存的数据是非结构化的,读取的时候没有表头等信息
使用hash结构存取:
<key,value>—>
<userid,name,xiaoming>
<userid,age,18>
mapreduce任务定时将用户信息从HBase导入到redis中;
获取数据时先从redis中获取,如果没有再到HBase中去获取,并同步到redis
redis集群操作
注意:
- 导入的数据量受限制于redis集群实例及内存配置,总容量=redis实例个数*单个实例的内存大小;
- 并且应尽量把数据拆分给多个key,使得数据负载均衡。
java API:
1.集群初始化
使用jedis
public RedisTest() {
//实例化一个集群的集合
Set<HostAndPort> hosts = new HashSet<HostAndPort>();
//通过ip地址和端口号获取到集群
hosts.add(new HostAndPort(”node01“, 6379));
int timeout = 5000;
client = new JedisCluster(hosts, timeout);
}
String类型存储:
public void testString() {
String key = "sid-user01";
// 设置指定key值,过期时间,sessionid
client.setex(key, 5, "A0BC9869FBC92933255A37A1D21167B2");
//获取指定的key值
String sessionId = client.get(key);
LOGGER.info("User " + key + ", session id: " + sessionId);
try {
Thread.sleep(10000);//进程休息
} catch (InterruptedException e) {
LOGGER.warn("InterruptedException");
}
sessionId = client.get(key);
LOGGER.info("User " + key + ", session id: " + sessionId);
key = "message";
//追加key,value
client.set(key, "hello");
String value = client.get(key);
LOGGER.info("Value: " + value);
client.append(key, " world");
value = client.get(key);
LOGGER.info("After append, value: " + value);
client.del(key);
}
hash类型存储:
public void testHash() {
String key = "userinfo-001";
// 以key,field,value的形式存入数据
client.hset(key, "id", "J001");
client.hset(key, "name", "John");
client.hset(key, "gender", "male");
client.hset(key, "age", "35");
client.hset(key, "salary", "1000000");
// get方式获取 一个字段的值
String id = client.hget(key, "id");
String name = client.hget(key, "name");
LOGGER.info("User " + id + "'s name is " + name);
Map<String, String> user = client.hgetAll(key);
LOGGER.info(user);
client.del(key);
key = "userinfo-002";
Map<String, String> user2 = new HashMap<String, String>();
user2.put("id", "L002");
user2.put("name", "Lucy");
user2.put("gender", "female");
user2.put("age", "25");
user2.put("salary", "200000");
client.hmset(key, user2);
//追加
client.hincrBy(key, "salary", 50000);
id = client.hget(key, "id");
String salary = client.hget(key, "salary");
LOGGER.info("User " + id + "'s salary is " + salary);
// like Map.keySet()
Set<String> keys = client.hkeys(key);
LOGGER.info("all fields: " + keys);
// like Map.values()
List<String> values = client.hvals(key);
LOGGER.info("all values: " + values);
// 获取多个字段的值
values = client.hmget(key, "id", "name");
LOGGER.info("partial field values: " + values);
// 判断key值是否已经存在
boolean exist = client.hexists(key, "gender");
LOGGER.info("Exist field gender? " + exist);
// 删除key
client.hdel(key, "age");
keys = client.hkeys(key);
LOGGER.info("after del field age, rest fields: " + keys);
client.del(key);
}
来源:CSDN
作者:TKE_aoliao
链接:https://blog.csdn.net/surijing/article/details/104573730