jedis API
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
util
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtil {
private static JedisPool jedisPool;
// 静态代码块,初始化 JedisPool
static {
// 配置连接池
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(128); // 最大连接数
config.setMaxIdle(64); // 最大空闲连接数
config.setMinIdle(16); // 最小空闲连接数
config.setTestOnBorrow(true); // 借用连接时进行有效性检查
config.setTestOnReturn(true); // 返回连接时进行有效性检查
config.setTestWhileIdle(true); // 连接空闲时进行有效性检查
config.setMinEvictableIdleTimeMillis(60000); // 最小空闲时间
config.setTimeBetweenEvictionRunsMillis(30000); // 清理线程的运行间隔
// 初始化连接池,设置 Redis 主机和端口
String redisHost = "你的ip"; // Redis 服务器地址
int redisPort = 6379; // Redis 端口
String password = "如果有密码";
int redisTimeout = 2000; // 连接超时时间,单位毫秒
int redisDatabase = 0; // 使用的数据库索引
jedisPool = new JedisPool(config, redisHost, redisPort,redisTimeout,password,redisDatabase);
}
// 获取 Jedis 实例
public static Jedis getJedis() {
return jedisPool.getResource();
}
// 关闭 Jedis 连接
public static void closeJedis(Jedis jedis) {
if (jedis != null) {
jedis.close(); // 关闭 Jedis 实例,归还给连接池
}
}
}
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class test01{
//通过创建单实例jedis对象连接redis服务
@Test
public void testJedisSingle() {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("name", "bar");
String name = jedis.get("name");
System.out.println(name);
jedis.close();
}
//使用连接池对redis连接进行共享,提高资源利用率,使用jedisPool连接redis服务
@Test
public void pool() {
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数
config.setMaxTotal(30);
//最大连接空闲数
config.setMaxIdle(2);
JedisPool pool = new JedisPool(config, "127.0.0.1", 6379);
Jedis jedis = null;
try {
jedis = pool.getResource();
jedis.set("name", "iguo");
String name = jedis.get("name");
System.out.println(name);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(jedis != null){
//关闭连接
jedis.close();
}
}
}
}
hash
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:
import com.qcby.util.RedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.*;
public class testHash {
@Test
public void testHsh() {
Jedis jedis = RedisUtil.getJedis();
try {
Map<String, String> pairs = new HashMap<String, String>();
pairs.put("name", "Akshi");
pairs.put("age", "2");
pairs.put("sex", "Female");
jedis.hmset("kid", pairs);
List<String> name = jedis.hmget("kid", "name");
System.out.println(name);
jedis.hdel("kid","age"); //删除map中的某个键值
System.out.println(jedis.hmget("kid", "pwd")); // 因为删除了,所以返回的是null
System.out.println(jedis.hlen("kid")); // 返回key为user的键中存放的值的个数
System.out.println(jedis.exists("kid"));// 是否存在key为user的记录
System.out.println(jedis.hkeys("kid"));// 返回map对象中的所有key
System.out.println(jedis.hvals("kid"));// 返回map对象中的所有value
Iterator<String> iter = jedis.hkeys("kid").iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println(key + ":" + jedis.hmget("kid", key));
}
List<String> values = jedis.lrange("messages", 0, -1);
values = jedis.hmget("kid", new String[] { "name", "age", "sex" });
System.out.println(values);
Set<String> setValues = jedis.zrange("hackers", 0, -1);
setValues = jedis.hkeys("kid");
System.out.println(setValues);
values = jedis.hvals("kid");
System.out.println(values);
pairs = jedis.hgetAll("kid");
System.out.println(pairs);
// 清空数据
System.out.println(jedis.flushDB());
// 添加数据
jedis.hset("hashs", "entryKey", "entryValue");
jedis.hset("hashs", "entryKey1", "entryValue1");
jedis.hset("hashs", "entryKey2", "entryValue2");
// 判断某个值是否存在
System.out.println(jedis.hexists("hashs", "entryKey"));
// 获取指定的值
System.out.println(jedis.hget("hashs", "entryKey")); // 批量获取指定的值
System.out.println(jedis.hmget("hashs", "entryKey", "entryKey1"));
// 删除指定的值
System.out.println(jedis.hdel("hashs", "entryKey"));
// 为key中的域 field 的值加上增量 increment
System.out.println(jedis.hincrBy("hashs", "entryKey", 123l));
// 获取所有的keys
System.out.println(jedis.hkeys("hashs"));
// 获取所有的values
System.out.println(jedis.hvals("hashs"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close(); // 归还给连接池
}
}
}
}
list
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
import com.qcby.util.RedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.List;
public class testList {
@Test
public void testList() {
System.out.println("==List==");
Jedis jedis = RedisUtil.getJedis();
try {
// 开始前,先移除所有的内容
jedis.del("messages");
jedis.rpush("messages", "11111");
jedis.rpush("messages", "22222");
jedis.rpush("messages", "33333");
// 再取出所有数据jedis.lrange是按范围取出,
// 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有
List<String> values = jedis.lrange("messages", 0, -1);
System.out.println(values);
// 清空数据
System.out.println(jedis.flushDB());
// 添加数据
jedis.lpush("lists", "vector");
jedis.lpush("lists", "ArrayList");
jedis.lpush("lists", "LinkedList");
// 数组长度
System.out.println(jedis.llen("lists"));
// 排序
//System.out.println(jedis.sort("lists"));
// 字串
System.out.println(jedis.lrange("lists", 0, 3));
// 修改列表中单个值
jedis.lset("lists", 0, "hello list!");
// 获取列表指定下标的值
System.out.println(jedis.lindex("lists", 1));
// 删除列表指定下标的值
System.out.println(jedis.lrem("lists", 1, "vector"));
// 删除区间以外的数据
System.out.println(jedis.ltrim("lists", 0, 1));
// 列表出栈
System.out.println(jedis.lpop("lists"));
// 整个列表值
System.out.println(jedis.lrange("lists", 0, -1));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close(); // 归还给连接池
}
}
}
}
String
redis中没有使用C语言的字符串表示,而是自定义一个数据结构叫SDS(simple dynamic string)即简单动态字符串。
c语言对字符串的存储是使用字符数组,遇到'\0'字符则认为字符串结束,redis的字符串可以存储任何类型的数据,因为任何类型数据都可以表示成二进制,sds结构中的char buf[]就是存储了二进制数据。
redis的字符串是二进制安全的,什么是二进制安全?简单理解就是存入什么数据取出的还是什么数据。redis中的sds不像c语言处理字符串那样遇到'\0'字符则认证字符串结束,它不会对存储进去的二进制数据进行处理,存入什么数据取出还是什么数据。
import com.qcby.util.RedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class testString {
@Test
public void Hello() {
Jedis jedis = RedisUtil.getJedis();
try {
// 向key-->name中放入了value-->minxr
jedis.set("name", "iguo");
String ss = jedis.get("name");
System.out.println(ss);//iguo
//在后面添加
jedis.append("name", "iguo2");
ss = jedis.get("name");
System.out.println(ss);
// 2、直接覆盖原来的数据
jedis.set("name", "iguo666");
System.out.println(jedis.get("name"));
// 删除key对应的记录
// jedis.del("name");
System.out.println(jedis.get("name"));// 执行结果:null
jedis.mset("name2", "iguo999", "age", "20");
System.out.println(jedis.mget("name2", "age"));
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisUtil.closeJedis(jedis);
}
}
@Test
public void testKey() {
Jedis jedis = RedisUtil.getJedis();
// 清空数据
System.out.println(jedis.flushDB());
//讲一个字符串给Redis并且返回该字符串
System.out.println(jedis.echo("foo"));
// 判断key否存在
System.out.println(jedis.exists("foo"));
jedis.set("key", "values");
System.out.println(jedis.exists("key"));
}
@Test
public void testString() {
Jedis jedis = RedisUtil.getJedis();
try {
// String
jedis.set("key", "Hello World!");
String value = jedis.get("key");
System.out.println(value);
// 清空数据
System.out.println(jedis.flushDB());
// 存储数据
jedis.set("foo", "bar");
System.out.println(jedis.get("foo"));
// 若key不存在,则存储
jedis.setnx("foo", "foo not exits");
System.out.println(jedis.get("foo"));//存在,因此不执行
// 覆盖数据
jedis.set("foo", "foo update");
System.out.println(jedis.get("foo"));
// 追加数据
jedis.append("foo", " hello, world");
System.out.println(jedis.get("foo"));
// 设置key的有效期,并存储数据
jedis.setex("foo", 2, "foo not exits");
System.out.println(jedis.get("foo"));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println(jedis.get("foo"));//值过期,返回null
// 获取并更改数据
jedis.set("foo", "foo update");
System.out.println(jedis.getSet("foo", "foo modify"));
// 截取value的值
System.out.println(jedis.getrange("foo", 1, 3));
System.out.println(jedis.mset("mset1", "mvalue1", "mset2", "mvalue2",
"mset3", "mvalue3", "mset4", "mvalue4"));
System.out.println(jedis.mget("mset1", "mset2", "mset3", "mset4"));
System.out.println(jedis.del(new String[] { "foo", "foo1", "foo3" }));
} catch (Exception e) {
e.printStackTrace();
} finally {
// 使用 close 方法返回连接
if (jedis != null) {
jedis.close(); // 归还给连接池
}
}
}
}
SortedSet
在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
import com.qcby.util.RedisUtil;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.Set;
public class testSortedSet {
@Test
public void sortedSet() {
Jedis jedis = RedisUtil.getJedis();
try {
jedis.zadd("hackers", 1940, "第三小");
jedis.zadd("hackers", 1953, "第三大");
jedis.zadd("hackers", 1965, "第二大");
jedis.zadd("hackers", 1916, "第二小");
jedis.zadd("hackers", 1969, "最大");
jedis.zadd("hackers", 1912, "最小");//1 最小
//从小到大
Set<String> setValues = jedis.zrange("hackers", 0, -1);
System.out.println(setValues);
//从大到小
Set<String> setValues2 = jedis.zrevrange("hackers", 0, -1);
System.out.println(setValues2);
// 清空数据
System.out.println(jedis.flushDB());
// 添加数据
jedis.zadd("zset", 10.1, "次大");
jedis.zadd("zset", 10.0, "次小");
jedis.zadd("zset", 9.0, "最小浮点数");
jedis.zadd("zset", 11.0, "最大浮点数");
// 元素个数
System.out.println(jedis.zcard("zset"));
// 元素下标
System.out.println(jedis.zscore("zset", "最小浮点数"));
// 集合子集
System.out.println(jedis.zrange("zset", 0, -1));
// 删除元素
System.out.println(jedis.zrem("zset", "最小浮点数"));
System.out.println(jedis.zcount("zset", 9.5, 10.5));
// 整个集合值
System.out.println(jedis.zrange("zset", 0, -1));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close(); // 归还给连接池
}
}
}
}
redis分片
有两个运行的redis就行
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import java.util.ArrayList;
import java.util.List;
public class redisShares {
public static void main(String[] args) {
share();
}
public static void share(){
List<JedisShardInfo> shares=new ArrayList<JedisShardInfo>();
JedisShardInfo jedisShardInfo1 = new JedisShardInfo("another ip", 6379);
JedisShardInfo jedisShardInfo2 = new JedisShardInfo("youip", 6379);
jedisShardInfo2.setPassword("yyl987@*");
shares.add(jedisShardInfo1);
shares.add(jedisShardInfo2);
ShardedJedis jedis = new ShardedJedis(shares);
jedis.setnx("xxxx","6666");
jedis.setnx("xxx","6666");
jedis.setnx("xx","6666");
System.out.println(jedis.get("xxxx"));
System.out.println(jedis.get("xxx"));
System.out.println(jedis.get("xx"));
}
}
redis主从复制
在从redis里面,redis.conf找
replicaof ip 端口
masterauth 如果主有密码
#bind 127.0.0.1
注释掉
protected-mode no
取消安全模式
主redis不用修改配置
有这个就行了