NoSQL第二次作业(1)
建立三个哨兵监听的主从集群,一主+三从+三个哨兵,Java客户端连接主从集群,实现增删改查
sentinel的增删改查嘛,最开始想用Python来搞,毕竟相比Java我对Python更熟,结果发现。。。Python对Redis的支持不够完善,反正各种bug
最开始用Windows下面的pycharm连服务器的Redis,报错找不到数据库
然后为了测试是不是服务器原因我又在Linux系统下面配了个Redis哨兵
这里说一下配置心得吧
服务器上面的时候由于是三台机子,所以说哨兵都指向主节点了,分别指向每个节点的时候主从切换会发生切换不了的错误。但是在一台机子上面安的时候哨兵指向每个节点也可以进行主从切换
服务器三个节点(一主二从)的时候主从切换都可以,但是再加入一个服务器,再配一个节点的时候,不管配不配置哨兵都不能主从切换,暂时未解决,只能一主二从三哨兵的配置
但是,Python连的时候依然报错,报错一样,都是找不到数据库
这里可以看见redis配置文件的权限变了,可以从另一个方向说明redis启动成功
emmm,报错依旧
百度只找到了一个同类问题,并且他的解决办法对我来说压根不好使
没办法,jedis连redis吧,连上之后都有成型的函数自己调用就行,没啥好玩的
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>redis3</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
</properties>
</project>
testSentinel.java
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.*;
/**
* 测试Redis哨兵模式
*/
public class TestSentinels {
@SuppressWarnings("resource")
@Test
public void testSentinel() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
jedisPoolConfig.setMinIdle(5);
// 哨兵信息
Set<String> sentinels = new HashSet<>(Arrays.asList("121.89.197.4:26379",
"39.101.133.206:26380","81.70.135.23:26381"));
// 创建连接池
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig,"123");
// 获取客户端
Jedis redis = pool.getResource();
redis.set("name", "wangjun1");
redis.set("id", "123456");
redis.set("address", "guangzhou");
//KEYS
Set keys = redis.keys("*");//列出所有的key,查找特定的key如:redis.keys("foo")
Iterator t1=keys.iterator() ;
while(t1.hasNext()){
Object obj1=t1.next();
System.out.println(obj1);
}
//DEL 移除给定的一个或多个key。如果key不存在,则忽略该命令。
redis.del("name");
Set keys1 = redis.keys("*");//列出所有的key,查找特定的key如:redis.keys("foo")
Iterator t11=keys1.iterator() ;
while(t11.hasNext()){
Object obj1=t11.next();
System.out.println(obj1);
}
// //DEL 移除给定的一个或多个key。如果key不存在,则忽略该命令。
// redis.del("name1");
//
// //TTL 返回给定key的剩余生存时间(time to live)(以秒为单位)
// redis.ttl("foo");
//
// //PERSIST key 移除给定key的生存时间。
// redis.persist("foo");
//
// //EXISTS 检查给定key是否存在。
// redis.exists("foo");
//
// //MOVE key db 将当前数据库(默认为0)的key移动到给定的数据库db当中。如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key,或者key不存在于当前数据库,那么MOVE没有任何效果。
// redis.move("foo", 1);//将foo这个key,移动到数据库1
//
// //RENAME key newkey 将key改名为newkey。当key和newkey相同或者key不存在时,返回一个错误。当newkey已经存在时,RENAME命令将覆盖旧值。
// redis.rename("foo", "foonew");
//
// //TYPE key 返回key所储存的值的类型。
// System.out.println(redis.type("foo"));
// //none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
//
// //EXPIRE key seconds 为给定key设置生存时间。当key过期时,它会被自动删除。
// redis.expire("foo", 5);//5秒过期
// //EXPIREAT EXPIREAT的作用和EXPIRE一样,都用于为key设置生存时间。不同在于EXPIREAT命令接受的时间参数是UNIX时间戳(unix timestamp)。
//
// //一般SORT用法 最简单的SORT使用方法是SORT key。
// redis.lpush("sort", "1");
// redis.lpush("sort", "4");
// redis.lpush("sort", "6");
// redis.lpush("sort", "3");
// redis.lpush("sort", "0");
//
// List list = redis.sort("sort");//默认是升序
// for(int i=0;i<list.size();i++){
// System.out.println(list.get(i));
// }
// // STRING 操作
//
// //SET key value将字符串值value关联到key。
// redis.set("name", "wangjun1");
// redis.set("id", "123456");
// redis.set("address", "guangzhou");
//
// //SETEX key seconds value将值value关联到key,并将key的生存时间设为seconds(以秒为单位)。
// redis.setex("foo", 5, "haha");
//
// //MSET key value [key value ...]同时设置一个或多个key-value对。
// redis.mset("haha","111","xixi","222");
//
// //redis.flushAll();清空所有的key
// System.out.println(redis.dbSize());//dbSize是多少个key的个数
//
// //APPEND key value如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
// redis.append("foo", "00");//如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
//
// //GET key 返回key所关联的字符串值
// redis.get("foo");
//
// //MGET key [key ...] 返回所有(一个或多个)给定key的值
// List list1 = redis.mget("haha","xixi");
// for(int i=0;i<list1.size();i++){
// System.out.println(list1.get(i));
// }
//
// //DECR key将key中储存的数字值减一。
// //DECRBY key decrement将key所储存的值减去减量decrement。
// //INCR key 将key中储存的数字值增一。
// //INCRBY key increment 将key所储存的值加上增量increment。
// //HSET key field value将哈希表key中的域field的值设为value。
// redis.hset("website", "google", "www.google.cn");
// redis.hset("website", "baidu", "www.baidu.com");
// redis.hset("website", "sina", "www.sina.com");
//
// //HMSET key field value [field value ...] 同时将多个field - value(域-值)对设置到哈希表key中。
// Map map = new HashMap();
// map.put("cardid", "123456");
// map.put("username", "jzkangta");
// redis.hmset("hash", map);
//
// //HGET key field返回哈希表key中给定域field的值。
// System.out.println(redis.hget("hash", "username"));
//
// //HMGET key field [field ...]返回哈希表key中,一个或多个给定域的值。
// List list2 = redis.hmget("website","google","baidu","sina");
// for(int i=0;i<list2.size();i++){
// System.out.println(list2.get(i));
// }
//
// //HGETALL key返回哈希表key中,所有的域和值。
// Map<String,String> map1 = redis.hgetAll("hash");
// for(Map.Entry entry: map1.entrySet()) {
// System.out.print(entry.getKey() + ":" + entry.getValue() + "\t");
// }
//
// //HDEL key field [field ...]删除哈希表key中的一个或多个指定域。
// //HLEN key 返回哈希表key中域的数量。
// //HEXISTS key field查看哈希表key中,给定域field是否存在。
// //HINCRBY key field increment为哈希表key中的域field的值加上增量increment。
// //HKEYS key返回哈希表key中的所有域。
// //HVALS key返回哈希表key中的所有值。
// //LPUSH key value [value ...]将值value插入到列表key的表头。
// redis.lpush("list", "abc");
// redis.lpush("list", "xzc");
// redis.lpush("list", "erf");
// redis.lpush("list", "bnh");
//
// //LRANGE key start stop返回列表key中指定区间内的元素,区间以偏移量start和stop指定。下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。你也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。
// List list3 = redis.lrange("list", 0, -1);
// for(int i=0;i<list3.size();i++){
// System.out.println(list3.get(i));
// }
//
// //LLEN key返回列表key的长度。
// //LREM key count value根据参数count的值,移除列表中与参数value相等的元素。
// //SADD key member [member ...]将member元素加入到集合key当中。
// redis.sadd("testSet", "s1");
// redis.sadd("testSet", "s2");
// redis.sadd("testSet", "s3");
// redis.sadd("testSet", "s4");
// redis.sadd("testSet", "s5");
//
// //SREM key member移除集合中的member元素。
// redis.srem("testSet", "s5");
//
// //SMEMBERS key返回集合key中的所有成员。
// Set set = redis.smembers("testSet");
// Iterator t2=set.iterator() ;
// while(t1.hasNext()){
// Object obj1=t2.next();
// System.out.println(obj1);
// }
//
// //SISMEMBER key member判断member元素是否是集合key的成员。是(true),否则(false)
// System.out.println(redis.sismember("testSet", "s4"));
//
// //SCARD key返回集合key的基数(集合中元素的数量)。
// //SMOVE source destination member将member元素从source集合移动到destination集合。
//
// //SINTER key [key ...]返回一个集合的全部成员,该集合是所有给定集合的交集。
// //SINTERSTORE destination key [key ...]此命令等同于SINTER,但它将结果保存到destination集合,而不是简单地返回结果集
// //SUNION key [key ...]返回一个集合的全部成员,该集合是所有给定集合的并集。
// //SUNIONSTORE destination key [key ...]此命令等同于SUNION,但它将结果保存到destination集合,而不是简单地返回结果集。
// //SDIFF key [key ...]返回一个集合的全部成员,该集合是所有给定集合的差集 。
// //SDIFFSTORE destination key [key ...]此命令等同于SDIFF,但它将结果保存到destination集合,而不是简单地返回结果集。
}
}
###运行结果
![][6]
附:一个增删改查(其实就用到了set,get和del)
test.java
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.*;
/**
* 测试Redis哨兵模式
*/
public class test {
private JedisSentinelPool pool;
private Jedis getConnection() {
return pool.getResource();
}
public void insert(String key, String value) throws Exception {
Jedis connection = getConnection();
String value1 = connection.get(key);
if(connection.get(key) != null) {
connection.close();
throw new Exception("插入失败,已经有名为"+key+"的键"+ ",value:" + value1);
}
else {
connection.set(key, value);
System.out.println("成功插入一组键值对" + "key:" + key + ",value:" + value);
}
connection.close();
}
public void delete(String key) throws Exception {
Jedis connection = getConnection();
String value = connection.get(key);
if(connection.get(key) == null) {
connection.close();
throw new Exception("删除失败,不存在名为"+key+"的键"+ ",value:" + value);
}
else {
System.out.println("成功删除一组键值对" + "key:" + key + ",value:" + value);
connection.del(key);
}
connection.close();
}
public void update(String key, String value) throws Exception {
Jedis connection = getConnection();
if(connection.get(key) == null) {
String value1 = connection.get(key);
connection.close();
throw new Exception("更新失败,不存在名为"+key+"的键"+ ",value:" + value1);
}
else {
connection.set(key, value);
System.out.println("成功更新一组键值对" + "key:" + key + ",value:" + value);
}
connection.close();
}
public String query(String key) {
Jedis connection = getConnection();
String value = connection.get(key);
String result = null;
if(value == null) {
System.out.println("查询结果,不存在名为"+key+"的键");
}
else {
result = value;
System.out.println("成功查找一组键值对"+"key:"+key+",value:"+value);
}
connection.close();
return result;
}
@SuppressWarnings("resource")
@Test
public void test() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(8);//资源池中的最大连接数
config.setMaxIdle(8); // 资源池允许的最大空闲连接数
config.setMinIdle(0);//资源池中的最大连接数
config.setBlockWhenExhausted(true);//当资源池用尽后,调用者是否要等待。只有当值为true时,下面的maxWaitMillis才会生效。
config.setMaxWaitMillis(3000);//当资源池连接用尽后,调用者的最大等待时间(单位为毫秒)。
config.setTestOnBorrow(false);//向资源池借用连接时是否做连接有效性检测(ping)。检测到的无效连接将会被移除。
config.setTestOnReturn(false);// 向资源池归还连接时是否做连接有效性检测(ping)。检测到无效连接将会被移除。
config.setJmxEnabled(true);//是否开启JMX监控
HashSet<String> sentinels = new HashSet<>();
sentinels.add("121.89.197.4:26379");
sentinels.add("39.101.133.206:26380");
sentinels.add("81.70.135.23:26381");
pool = new JedisSentinelPool("mymaster",sentinels, config,"123");
try {
insert("name", "test1");
}
catch(Exception e) {
System.out.println(e.getMessage());
}
try {
update("name", "test3");
}
catch(Exception e) {
System.out.println(e.getMessage());
}
try {
query("name");
}
catch(Exception e) {
System.out.println(e.getMessage());
}
try {
delete("name");
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}