Linux命令大全与Redis,RedisUtil工具类
Linux操作
1.基本操作
配置相关
nohup java -jar xxx.jar >/usr/local/temp.txt &
部署应用
su root
切换到管理员
ifconfig
查看网络设置
dhclient
让linux自动分配一个ip地址
vim /etc/sysconfig/network-scripts/ifcfg-ens33
设置IP地址、子网掩码和网关
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=227bafca-71c3-4516-8853-279b1c571979
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.81.83
NETMASK=255.255.255.0
GATEWAY=192.168.81.2
systemctl restart network.service
重启网卡
ping的时候可以用CTRL+C结束
hostname
查看hostname
hostnamectl set-hostname xxxxx
修改hostname
同时在Windows里面修改host文件 ip hostname
vim /etc/sysconfig/iptables
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8888 -j ACCEPT
(8888|888|80|443|20|21)
service iptables stop –停止
service iptables start –启动
sync 将数据由内存同步到硬盘
shutdown -h 10 10分钟后关机
shutdown -h 20:20 指定时间关机
reboot 重启
mv xxxx xxxx(移动什么文件到什么文件夹)
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
宝塔面板安装命令
systemctl status firewalld 查看当前防火墙状态。
systemctl stop firewalld 关闭当前防火墙。
systemctl disable firewalld开机防火墙不启动。
目录管理
cd / 到根目录
cd … 上一级目录
ls
列出目录
- -a 查看所有文件
- -l 查看文件各种属性
上下键切换命令(这样就不用每次重输入了)
mkdir xxx 创建文件夹
- mkdir -p t/t1/t2 递归创建目录,t目录下的t1下的t2
pwd 显示当前目录
rmdir xxx 删除空文件夹
- rmdir -p xxx 删除不为空的文件夹
rm (移除目录或文件)
- -f 忽略不存在的文件
- -r 递归删除目录
- -i 互动,询问是否删除
cp 源文件 目标目录 复制文件
mv 源文件 目标目录 移动文件(也可以重命名文件夹)
基本属性
boot文件的第一个属性
- d代表目录
- -代表文件
- l代表link
- b代表接口设备
- c代表串行端口设备
chmod
更改用户权限
r:4 r:2 x:1
可读可写不可执行 rw- 6
chmod 777 filename
所有用户可读可写可执行
2,5,8写
3,6,9执行
网络配置目录
cd /etc/sysconfig/network-scripts
文件操作
cat
查看文件
tac倒过来看
nl显示行号
more xxx
可以翻页看 回车一行一行读,回车翻页
less xxx
与more类似 但可以上下键 q退出
查看文件后 输入 /字符串 向下搜索 ?字符串 向上查询
n是下一个 N反向
touch 创建文件
ln f1 f2 f2是f1的硬链接
ln -s f1 f2 f2是软链接
查找文件
1.linux下最强大的搜索命令为”find“。
格式为”find <指定目录> <指定条件> <指定动作>“;
如使用find命令搜索在根目录下的所有interfaces文件所在位置,命令格式为”
find / -name 'interfaces'
“
2.使用locate搜索linux系统中的文件,它比find命令快。因为它查询的是数据库(/var/lib/locatedb),数据库包含本地所有的文件信息。使用locate命令在根目录下搜索interfaces文件的命令为”
locate interfaces
“
3.使用”whereis“命令可以搜索linux系统中的所有可执行文件即二进制文件。使用whereis命令搜索grep二进制文件的命令为”whereis grep“。
4.使用which命令查看系统命令是否存在,并返回系统命令所在的位置。使用which命令查看grep命令是否存在以及存在的目录的命令为”which grep“。
5.使用type命令查看系统中的某个命令是否为系统自带的命令。使用type命令查看cd命令是否为系统自带的命令;查看grep 是否为系统自带的命令。
vim编辑器
命令模式
> i 切换到编辑
> x删除当前字符
> : 切换到底线命令模式
> 数字加回车,相对移动到第几行
> / 搜素
> set nu
> u 撤销
> Ctrl+r 重做
输入模式
底线命令模式
w 保存
q 退出
用户管理
> useradd -选项 添加用户
> useradd -m xxx 自动创建用户的主目录xxx
> passwd xxx 添加密码
> passwd -l xxx 锁定账户(lock)
> passwd -d xxx 锁定账户(通过删除了密码不能登录)
> userdel -r xxx 删除用户,-r一并删除目录
> cat /ets/passwd 查看用户信息
用户组管理
cat /etc/group 查看用户组
groupadd xxx 添加
groupdel xxx 删除
groupmod xxx 修改
切换用户组
磁盘管理
> du命令
> 显示文件或目录所占用的磁盘空间。
> 命令格式:
> du [option] 文件/目录
> -h 输出文件系统分区使用的情况,例如:1KB,1MB,1GB等
> -s 显示文件或整个目录的大小,默认单位是KB
> df [option] 文件/目录
> 检查linux服务器的文件系统的磁盘空间占用情况
进程管理
ps -a `查看所有进程信息`
-u `以用户信息显示`
-x `显示后台进程参数`
ps -aux `查看所有进程`
ps -aux|grep mysql `过滤出mysql的进程信息显示出来(|)`
ps -ef|grep php `可以看到父进程`
pstree -pu|grep php `查看进程树`
kill -9 进程id `结束进程`
2.安装软件
> rpm -ivh rpm包 安装jdk
> rpm -qa|grep jdk 查看jdk
> rpm -e --nodeps jdk包 卸载jdk
> `配置环境变量`
> vim /etc/profile
> 最后添加
> >JAVA_HOME=/usr/java/jdkxxx (去目录找)
> >CLASSPATH=%JAVA_HOME%lib;%JAVA_HOME%/jre/lib
> >PATH=$JAVA_HOME/bin;$JAVA_HOME/jre/bin
> >export PATH CLASSPATH JAVA_HOME
> Tomcat
> tar -zxvf apache-tomcat-9.0.22.tar.gz 解压
> ./startup.sh 启动Tomcat
> ./shutdown.sh 停止Tomcat
> > firewall-cmd --zone=public --add-port=8080/tcp --permanent 开启端口
> > systemctl restart firewall.service 重启防火墙
ls等命令无法使用,输入以下指令
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
3.执行程序
> nohup java -jar xxx.jar >/usr/local/temp.txt &
> 查看端口是否被占用
> netstat -lnp|grep 80
> kill -9 pid
4.Navcat连接虚拟机的mysql
1.Xshell连接虚拟机上的mysql
2.mysql -uroot -proot (替换自己的用户名密码)
3.show databases
4.use mysql (选中了mysql数据库)
5.show tables (显示表)
6.select user,host from user
7.root对应的localhost需要修改为%
8.看数据结构,update user set host="%" where host="localhost"
或者update user set host="%" where user="root"
9.flush privileges; (使修改立即生效)
10.这时候就可以去连接了.
5.redis-cli.
如何启动redis
redis ==>数据库,缓存,消息中间件
五种数据类型strings / hashs / lists / sets / sorted sets
`ps -ef|grep redis`#查看redis进程(在命令行下)
#启动redis,首先要知道redis-server位置,还要知道redis.conf位置
**使用`locate redis-server` 和 `locate redis.conf`**
#接着使用下面指令
**/usr/local/bin/redis-server /www/server/redis/redis.conf**
`netstat -nplt`#可以查看是否启动成功
#连接edis
`redis-cli -p 6379`#(下面语句在redis下)
`set key xxx`
`get key`
`keys *` #所有key
`shutdown`--> `exit`#退出redis
#测试redis-benchmark
`redis-benchmark -h localhost -p 6379 -c 100 -n 100000`
#共16个数据库
select * #切换数据库
dbsize #查看数据库大小
flushdb #清空当前库
flushall #清空所有数据库
exists name #判断name是否存在
move name 1 #移动name到数据库1
del name #删除key
expire name 10 #十秒后过期
这时候使用ttl #name查看他的时间
type name #查看name类型
append name "hello" #在name后追加hello
strlen name #看name长度
Strings
set views 0
incr views #views加1
decr views #views减1
incrby views 10 #增长10
decrby views 10 #减10
getrange name 0 3 #截取字符串[0,3]
getrange name 0 -1 #截取全部字符串
#替换 name=abcd
setrange name 1 xx #从1位开始替换两位 变成 axxd
setex (set with expire)#设置过期时间
setnx (set if not exist)#不存在再设置
mset k1 v1 k2 v2 k3 v3 #批量设置
msetnx k1 v1 k2 v2 #接上一条指令,会设置失败,因为已经存在,要么都成功,要么都失败
set user:1 {name:zhangsan,age:12}
mset user:1:name zhangsan user:2:age 2
getset name xxx # 先get再set,不存在会返回nil但是也会创建
List
所有list命令l开头
lpush是将一个或多个值插入到头部 (leftpush)
lpush list one
lpush list two
lpush list three
lrange list 0 -1 #拿全部值
lrange list 0 1 #拿到 three 和 two 栈,先进后出
rpush #是将一个或多个值插入到尾部
lpop #头部移除
rpop #尾部移除
lindex list 1 #通过下标获取值
llen list #查看长度
lrem list 1 one #移除指定的值 one一次
lrem list 2 three #移除指定值three 两次
######################################################
trim #修剪
ltrim list 1 2 #从头部 1, 2 位置截取剩下2个
(如 lpush list a b c d e,(e为头部)
ltrim list 1 2后
lrange list 0 -1 结果为 d c )
rtrim
#####################################################
rpoolpush list newlist #移除list最后一个元素并添加到新列表
lset list 1 item #在list指定下标赋值
linsert list before "b" "z" #b 前面插入 z
linsert list after "b" "z" #b 后面插入 z
set
set 无序的
里面的值不允许重复
sadd myset "hello"
sadd myset "hello1"
sadd myset "hello2"
smembers myset #查看
sismember myset hello #返回1 已存在 无法插入
sismember myset hello4 #返回0 不存在,可以加入
scard myset #获取myset元素个数
srem myset hello #移除set中的元素hello
set 抽取随机元素
srandmember myset
spop 随机弹出元素
smove myset myset2 "hello"
##################################################
sdiff set1 set2 #差集
sinter set1 set2 #交集,共同好友
sunion set1 set2 #并集
hash
hash(哈希) Map集合
hset myhash field1 a
hget myhash field1 # 获取字段值
hmset myhash field1 a field2 b #同时设置多个hash
hgetall myhash #获取全部hash
hexists myhash field1 #判断field1是否存在
hsetnx myhash field1 hello #不存在才创建
hincrby myhash field1 1 #给field+1
Zset 有序的set
zadd myset 1 one
zadd myset 2 two
zadd myset 3 three
可以排序,比如工资
zadd salary 2500 xiao
zadd salary 3000 zhang
zadd salary 500 da
zrevrange myset 0 -1 倒序
zrangebyscore salary -inf +inf (负无穷到正无穷)
zrevrangebyscore myset 10000 100(倒序)
zcount myset 1 10 获取1到10间的成员数量
三种特殊数据类型
geospatial 地理位置
推算两地距离,附近人
geoadd china:city 纬度 经度 城市
geoadd china:city 116.397128 39.916527 beijing
geoadd china:city 121.48941 31.40527 shanghai
geoadd china:city 106.54041 29.40268 chongqing
geoadd china:city 106.54041 29.40268 chongqing
#java可以批量导入地理数据
geopos china:city beijing #查询地理位置
两人之间的距离
geodist
m:米
km:千米
mi:英里
ft:英尺
geodist china:city beijing chongqing km #km设置单位
附近的人,先获得定位,通过半径查询.
georadius
georadius china:city 110 30 1000 km
#查询经度110 纬度30范围1000km之内的城市
georadius china:city 110 30 1000 km withdist
#显示指定位置指定距离内城市与其距离
georadius china:city 110 30 1000 km withcoord
#显示位置的指定范围的城市的定位信息
georadius china:city 110 30 1000 km withdist withcoord count 2 #筛选出两个指定的结果,包含距离和定位信息
georadiusbymember china:city beijing 1500 km
#找出指定元素范围内的元素名称
geahash字符串属性,将二维经纬度转为一维的字符串
geohash china:city beijing
"wx4g0dtf9e0"
`底层是zset,所以可以通过zet进行操作,比如移除元素等`
zrange china:city 0 -1 #查询所有元素
zrem china:city beijing #移除北京这个元素
Hyperloglog:基数统计的算法
基数:不重复的元素
A{1,3,5,6,5}==>A{1,3,5,6}
简介
网站的UV(一个人访问多次算一个人)
优点:只需要12kb内存.2^64个元素,错误率低 0.81%,统计UV合适
pfadd my a b c d e c d s c v d a s a #添加元素
pfcount my #统计不同元素数量 7
pfadd me c d c s a x s c z #添加第二组
pfmerge new my me #合并my和me成new.
pfcount new #统计出new的基数数量
pfadd x 逐个添加时,重复的会添加失败
Bitmaps
位存储
统计用户信息,活跃,不活跃,登录,未登录,打卡.只有两个状态就可以使用
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0
七天sign的设置情况
查看某一天的bit值
getbit sign 5
0
#统计这周打卡记录
bitcount sign
事务(伪事务)
redis单条命令保证原子性,
但是事务不保证原子性
redis 没有隔离级别的概念
开启事务
命令入列
执行事务(exec)
乐观锁
监视器watch
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set k1 v1 #命令入队
QUEUED
127.0.0.1:6379> set k2 v2 #命令入队
QUEUED
127.0.0.1:6379> set k3 v3 #命令入队
QUEUED
127.0.0.1:6379> get k1 #命令入队
QUEUED
127.0.0.1:6379> exec #执行
1) OK
2) OK
3) OK
4) "v1"
放弃事务: discard
编译型异常,所有代码都不会执行
运行时异常,错误命令异常,其他命令正常执行
监控
悲观锁:
乐观锁:
redis监控测试
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
#使用watch可以当乐观锁操作,watch后如果冲突会执行失败
失败后,
再watch
再开启事务
再命令入列
执行
Jedis
Java操作redis的中间件
新建java springboot项目,导入jedis,fastjson
@Test
void test() {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("name", "fuckyou");
System.out.println("清空数据: "+jedis . flushDB());
System.out.println("判断某个键是否存在: " + jedis.exists("username"));
System.out.println("新增< 'username', ' user'>的键值对: " + jedis.set("username", "ku"));
System.out.println("新增<'password' , ' password'>的键值对: " + jedis.set("password", "pas"));
System. out. print("系统中所有的键如下: ");
Set<String> keys = jedis. keys( "*");
System. out . println(keys);
System . out . println( "删除键password: "+jedis . del( "password"));
System. out . println( "判断键password是否存在: "+jedis. exists( "password"));
System . out . println( "查看键username所存储的值的类型: "+jedis. type( "username"));
System. out . println( "随机返回key空间的一个: "+jedis . randomKey());
System . out . println("重命名 "+jedis . rename( "username", "name" ));
System . out. println( "取出改后的name: "+jedis. get("name"));
System. out. println("按索引查询: "+jedis. select( 0));
System. out . println( "删除当前选择数据库中的所有key: "+jedis . flushDB());
System. out . println("返回当前数据库中key的数目: "+jedis. dbSize());
System. out . println("删除所有数据库中的所有key: "+jedis.flushAll());
}
事务:
@Test
void test() {
Jedis jedis = new Jedis("127.0.0.1", 6379);
Transaction multi = jedis.multi();
JSONObject object = new JSONObject();
object.put("k1", "v1");
object.put("k2", "v2");
String toJSONString = object.toJSONString();
try {
multi.set("user1", toJSONString);
multi.exec();//执行事务
} catch (Exception e) {
multi.discard();//放弃事务
e.printStackTrace();
}finally {
System.out.println(jedis.get("user1"));
jedis.close();//最后关闭连接
}
}
springboot操作
pom.xml引入包 spring-boot-starter-data-redis
新建项目界面nosql中的第一个redis
jedis已经不使用了,直连不安全,BIO模式
用的lettuce,采用netty,多线程中进行共享,减少线程数据.NIO模式
即可知道redis相关配置
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
#spring.redis.host=127.0.0.1
#spring.redis.port=6379
#spring.redis.lettuce.pool.max-active=8
#等等..默认lettuce.基本不需要自己配置
@SpringBootTest
class DemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
}
@Test
void Test() {
redisTemplate.opsForValue().set("k1", "v1");
redisTemplate.opsForList().leftPush("k2", "v2");
List k2 = redisTemplate.opsForList().range("k2", 0, -1);
System.out.println(k2);
redisTemplate.opsForSet();
redisTemplate.opsForHash();
redisTemplate.opsForZSet();
redisTemplate.opsForGeo();
redisTemplate.opsForHyperLogLog();
}
}
关键代码:
@Autowired
private RedisTemplate redisTemplate;//接着使用即可
redisTemplate.opsForValue().set(“k1”, “v1”);//操作string
redisTemplate.opsForList().leftPush(“k2”, “v2”);//操作list
List k2 = redisTemplate.opsForList().range(“k2”, 0, -1);
System.out.println(k2);
redisTemplate.opsForSet();//操作set
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForZSet();//操作zset
redisTemplate.opsForGeo();//操作geo
redisTemplate.opsForHyperLogLog();//操作基数
删除数据需要另外获取连接
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushAll();//删除所有数据
connection.flushDb();//删除数据
如果不进行对象序列号,会报错,需要自己执行序列号操作
` class User`
@Component//方便直接调用
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private Integer age;
}
` Test `
@Test
void Test() throws JsonProcessingException {
User user = new User("哈哈", 10);
String s = new ObjectMapper().writeValueAsString(user);//不序列号不行,所有可以在pojo里面对象直接序列号
redisTemplate.opsForValue().set("user", s);
Object user1 = redisTemplate.opsForValue().get("user");
System.out.println(user1);
}
因此,直接创建对象的时候序列号,就不会报错
@Component//方便直接调用 @Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { private String name; private Integer age; }
@Test void Test() throws JsonProcessingException { User user = new User("哈哈", 10); // String s = new ObjectMapper().writeValueAsString(user);//不序列号不行,所有可以在pojo里面对象直接序列号 redisTemplate.opsForValue().set("user", user); Object user1 = redisTemplate.opsForValue().get("user"); System.out.println(user1); }
自己的redisTemplate配置
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
redisUtil 工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*
* @author zhangzhixiang
* @date 2019年06月19日
*/
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
测试
@SpringBootTest
class DemoApplicationTests {
@Autowired
private RedisUtil redisUtil;
@Test
void contextLoads() {
}
@Test
void Test() throws JsonProcessingException {
User user = new User("哈哈", 10);
redisUtil.set("user1", user);
Object user1 = redisUtil.get("user1");
System.out.println(user1);
}
}
redis.conf
locate redis.conf
cd ..到目录
vim redis.conf
网络
bind 127.0.0.1
protected-mode yes
port 6379
daemonize yes #守护进程方式运行,如果是no需改为yes
loglevel notice #日志
logfile "/www/server/redis/redis.log"
databases 16 #默认16个数据库
always-show-logo yes #显示logo
# save "" 持久化规则
save 900 1 #900内,有一个key进行修改,进行持久化
save 300 10 #300秒内,10个key进行修改就持久化
save 60 10000 #60秒内10000次修改则持久化
stop-writes-on-bgsave-error yes #持久化错误后默认继续工作
rdbcompression yes #是否压缩
rdbchecksum yes #保存rdb时候进行校验
dbfilename dump.rdb
dir /www/server/redis/ #rdb保存文件目录
################ REPLICATION ####################
主从复制
########## SECURITY #############
可以设置密码
config get requirepass 获取密码
>requirepass 123456 #如果在### SECURITY #####加上这句,就会设置密码
或者直接命令设置:
config set requirepass "123456"
这样下次需要先`auth 123456` 才可以继续操作
############## CLIENTS #################
# maxclients 10000 #最大客户数
# maxmemory-policy noeviction #内存策略
################ APPEND ONLY MODE #############
AOF配置
appendonly no #默认不开启,默认rdb持久化,大部分时间够用了
appendfilename "appendonly.aof" #持久化文件名字
save 保存配置文件设置
Redis持久化
RDB==> dump.rdb
locate dump.rdb 定位dump.rdb
执行flushall,退出redis都会产生rdb文件
如果需要恢复rdb,则定位dir,后续待补充
127.0.0.1:6379> config get dir
1) "dir"
2) "/www/server/redis"
AOF如果有错位,redis无法启动,需要修复这个文件
redis-check-aof --fix appendonly.aof
Redis发布订阅
subscribe channel #订阅频道
publish channel "hello" #发送消息到频道
*Redis主从复制
主从复制,读写分离,主写从读
一主二从,集群至少需要三台服务器
默认都是主,变成从需要配置
info replication
查看信息
如何设置为从机
slaveof 127.0.0.1 6379
即slaveof ip port
认主机为老大
masterauth password
验证主机密码
slave no one
自己当主机,手动的
出现了哨兵模式.就自动了
哨兵模式 sentinel
(自动选举主机)
真正实施需要六个进程:三个哨兵互相监督.
# 禁止保护模式
protected-mode no
# 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,1代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
sentinel monitor mymaster 192.168.81.83 6379 1
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456
启动哨兵模式:与启动redis类似
/www/server/redis/src/redis-sentinel /www/server/redis/sentinel.conf