04_NET中使用Redis(ServiceStack.Redis)和Linux中安装Redis(docker安装和普通安装)
官网:Redis - The Real-time Data Platform
Linux安装Redis:
1.安装gcc
安装gcc yum -y install gcc tcl 如果出现Complete 表示成功
查看gcc版本 gcc -v
2.升级gcc
升级到gcc 9.3: yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash 需要注意的是scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本。 如果要长期使用gcc 9.3的话: echo -e "\nsource /opt/rh/devtoolset-9/enable" >>/etc/profile 查看gcc版本 [root@node01 ~]# gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-9/root/usr --mandir=/opt/rh/devtoolset-9/root/usr/share/man --infodir=/opt/rh/devtoolset-9/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-9.3.1-20200408/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux Thread model: posix gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
3.安装Redis
载redis安装包 wget http://download.redis.io/releases/redis-6.2.5.tar.gz
如果出现了command not found 则要安装wget
yum install -y wget
解压安装包 [root@node01 modules]# tar -zxvf redis-6.2.5.tar.gz 进入安装包 [root@node01 modules]# cd redis-6.2.5/ 编译和安装 make && make test && make install
编译出错时,清出编译生成的文件
make distclean
卸载
make uninstall
4.配置Redis
将服务端脚本和客户端脚本移动到新建的文件夹下面
在安装目录下创建一个 bin 目录 [root@node01 redis-6.2.5]# mkdir bin [root@node01 redis-6.2.5]# cd src/
将 redis-server 和 redis-cli 移动到 bin 目录中 [root@node01 src]# cp redis-server ../bin/ [root@node01 src]# cp redis-cli ../bin/ [root@node01 src]# cd .. [root@node01 redis-6.2.5]# ls 00-RELEASENOTES BUGS CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests utils bin CONDUCT COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src TLS.md
将 redis 的配置文件 redis.conf 移动到 bin 目录下 [root@node01 redis-6.2.5]# cp redis.conf bin/ [root@node01 redis-6.2.5]# cd bin/ [root@node01 bin]# ls redis-cli redis.conf redis-server 修改配置文件,修改的内容在下面 [root@node01 bin]# vim redis.conf [root@node01 bin]# ./redis-server redis.conf [root@node01 bin]# ./redis-cli 127.0.0.1:6379> set test hello OK 127.0.0.1:6379> get test "hello"
配置redis.conf 文件
设置可以访问redis服务的IP,0,0,0,表示可以远程访问 bind 0.0.0.0 设置redis的访问端口 port 6379 设置访问redis的密码 requirepass 123456 设置 redis-server 以守护线程方式启动 daemonize yes
启动redis
启动 redis 服务, 后面加 & 参数后台表示启动 $REDIS_HOME/bin/redis-server redis.conf & 查看 redis 进程是否启动 [root@localhost bin]# ps -ef | grep redis root 85823 62546 0 23:54 pts/1 00:00:00 ./redis-server 0.0.0.0:6379 root 85839 83082 0 23:55 pts/2 00:00:00 grep --color=auto redis 启动 redis 的客户端 $REDIS_HOME/bin/redis-cli 登录 redis auth [yourpassword]
开启自启动
创建开机自启动脚本的文件
vim /etc/init.d/redis
编写开机自启动的脚本, 注意替换自己的redis的启动命令的位置以及配置文件的位置
case "$1" in start) if [ -f $PIDFILE ] then echo "$PIDFILE exists, process is already running or crashed" else echo "Starting Redis server..." # 启动 Redis $EXEC $CONF fi ;; stop) if [ ! -f $PIDFILE ] then echo "$PIDFILE does not exist, process is not running" else PID=$(cat $PIDFILE) echo "Stopping ..." # $CLIEXEC -p $REDISPORT shutdown # 带有密码的redis关闭方式: redis-cli -a 123456 shutdown $CLIEXEC -a 123456 shutdown while [ -x /proc/${PID} ] do echo "Waiting for Redis to shutdown ..." sleep 1 done echo "Redis stopped" fi ;; status) if [ ! -f $PIDFILE ] then echo 'Redis is not running' else PID=$(cat $PIDFILE) if [ ! -x /proc/${PID} ] then echo 'Redis is not running' else echo "Redis is running ($PID)" fi fi ;; restart) $0 stop $0 start ;; *) echo "Please use start, stop, restart or status as first argument" ;; esac
设置开机自启动
为redis开机启动脚本赋予执行权限 chmod +x /etc/init.d/redis 开启redis服务 systemctl start redis 查看redis的状态 systemctl status redis 停止redis服务 systemctl stop redis 查看redis服务的状态 systemctl status redis 设置redis开机自启动 systemctl enable redis 设置禁止redis开机自启动 systemctl disable redis
------------------------------------------------------------------------------漂亮的分割线-----------------------------------------------------------------
Docker安装Redis
最新版
docker pull redis
指定版
docker pull redis:xxx
查看镜像
docker images
创建容器并启动运行
docker run \ --restart=always \ --log-opt max-size=100m \ --log-opt max-file=2 \ -p 6379:6379 \ --name redis \ -v /home/redis/myredis/myredis.conf:/etc/redis/redis.conf \ -v /home/redis/myredis/data:/data \ -d redis redis-server /etc/redis/redis.conf \ --appendonly yes \ --requirepass 123456
--restart=always : redis启动方式:开机启动 --log-opt : 日志配置 -p 6379:6379 : 主机与容器映射端口 --name : 容器名称,多个不要重复 -v : 挂载地址,主机地址:容器地址 -d redis redis-server /etc/redis/redis.conf : Redis启动时使用redis.conf 配置文件 --appendonly yes : 开启持久化 --requirepass : 密码
查看容器
docker ps
关闭容器
docker stop redis
启动容器
docker start redis
NET6中使用ServiceStack.Redis
安装包:ServiceStack.Redis
1.配置文件信息
/// <summary> /// Redis配置文件信息 /// </summary> public class RedisConfigurationInfo { /// <summary> /// 可写的Redis链接地址 /// format:ip1,ip2 /// 默认6379端口 /// </summary> public string WriteServerList = "127.0.0.1:6379"; /// <summary> /// 可读的Redis链接地址 /// format:ip1,ip2 /// </summary> public string ReadServerList = "127.0.0.1:6379"; /// <summary> /// 最大写链接数 /// </summary> public int MaxWritePoolSize = 60; /// <summary> /// 最大读链接数 /// </summary> public int MaxReadPoolSize = 60; /// <summary> /// 本地缓存到期时间,单位:秒 /// </summary> public int LocalCacheTime = 180; /// <summary> /// 自动重启 /// </summary> public bool AutoStart = true; /// <summary> /// 是否记录日志,该设置仅用于排查redis运行时出现的问题, /// 如redis工作正常,请关闭该项 /// </summary> public bool RecordeLog = false; }
2.创建Redis链接
/// <summary> /// 创建Redis链接 /// </summary> public class RedisManager { /// <summary> /// redis配置文件信息 /// </summary> private static RedisConfigurationInfo RedisConfigInfo = new RedisConfigurationInfo(); /// <summary> /// Redis客户端池化管理 /// </summary> private static PooledRedisClientManager prcManager; /// <summary> /// 静态构造方法,初始化链接池管理对象 /// </summary> static RedisManager() { CreateManager(); } /// <summary> /// 创建链接池管理对象 /// </summary> private static void CreateManager() { string[] WriteServerConStr = RedisConfigInfo.WriteServerList.Split(','); string[] ReadServerConStr = RedisConfigInfo.ReadServerList.Split(','); prcManager = new PooledRedisClientManager(ReadServerConStr, WriteServerConStr, new RedisClientManagerConfig { MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize, MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize, AutoStart = RedisConfigInfo.AutoStart, }); } /// <summary> /// 客户端缓存操作对象 /// </summary> public static IRedisClient GetClient() { return prcManager.GetClient(); } }
3.实现Redis内操作方法
public class RedisBase : IDisposable { public IRedisClient client { get; private set; } /// <summary> /// 构造时完成链接的打开 /// </summary> public RedisBase2() { client = RedisManager.GetClient(); } #region 字符串 public List<string> getAllKeys() { return this.client.GetAllKeys(); } /// <summary> /// 设置值 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void setString(string key, string value) { this.client.Set(key, value); } /// <summary> /// 设置值,带过期时间 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expiresIn"></param> public void setString(string key, string value, TimeSpan expiresIn) { this.client.Set(key, value, expiresIn); } /// <summary> /// 是否存在 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool containsKey(string key) { return this.client.ContainsKey(key); } /// <summary> /// 设置字典 /// </summary> /// <param name="dic"></param> public void setAll(Dictionary<string, string> dic) { this.client.SetAll(dic); } /// <summary> /// 返回旧值,设置新值 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public string getAndSetValue(string key, string value) { return this.client.GetAndSetValue(key, value); } /// <summary> /// 获取对应的值 /// </summary> /// <param name="key"></param> /// <returns></returns> public string getValue(string key) { return this.client.GetValue(key); } public string getRandomKey() { return this.client.GetRandomKey(); } /// <summary> /// 追加值到现有key中 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void appendToValue(string key, string value) { this.client.AppendToValue(key, value); } #endregion #region List /// <summary> /// (队列操作)增加一个值到列表 /// </summary> /// <param name="listId"></param> /// <param name="value"></param> public void enqueueItemOnList(string listId, string value) { this.client.EnqueueItemOnList(listId, value); } /// <summary> /// 从队列中出一个 /// </summary> /// <param name="listId"></param> /// <returns></returns> public string dequeueItemFromList(string listId) { return this.client.DequeueItemFromList(listId); } /// <summary> /// 栈,增加一个值到列表 /// </summary> /// <param name="listId"></param> /// <param name="value"></param> public void pushItemToList(string listId, string value) { this.client.PushItemToList(listId, value); } /// <summary> /// 栈,从当前列表中出一个值,并返回 /// </summary> /// <param name="listId"></param> /// <returns></returns> public string popItemFromList(string listId) { return this.client.PopItemFromList(listId); } /// <summary> /// 获取某一个位置的值 /// </summary> /// <param name="listId"></param> /// <param name="index"></param> /// <returns></returns> public string getItemFromList(string listId, int index) { return this.client.GetItemFromList(listId, index); } /// <summary> /// 设置并修改指定位置的值 /// </summary> /// <param name="listId"></param> /// <param name="index"></param> /// <param name="value"></param> public void setItemInList(string listId, int index, string value) { this.client.SetItemInList(listId, index, value); } /// <summary> /// 获取列表所有的值 /// </summary> /// <param name="listId"></param> /// <returns></returns> public List<string> getAllItemsFromList(string listId) { return this.client.GetAllItemsFromList(listId); } /// <summary> /// 删除所有内容 /// </summary> /// <param name="listId"></param> public void removeAllFromList(string listId) { this.client.RemoveAllFromList(listId); } /// <summary> /// 删除列表指定元素 /// </summary> /// <param name="listId"></param> /// <param name="attr"></param> public void removeItemFromList(string listId, string value) { this.client.RemoveItemFromList(listId, value); } /// <summary> /// 获取指定列表的长度 /// </summary> /// <param name="listId"></param> /// <returns></returns> public long getListCount(string listId) { return this.client.GetListCount(listId); } #endregion #region Hash /// <summary> /// 设置Hash的值 /// </summary> /// <param name="hashId"></param> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public bool setEntryInHash(string hashId, string key, string value) { return this.client.SetEntryInHash(hashId, key, value); } /// <summary> /// 获取Hash中的值 /// </summary> /// <param name="hashId"></param> /// <param name="key"></param> /// <returns></returns> public string getValueFromHash(string hashId, string key) { return this.client.GetValueFromHash(hashId, key); } /// <summary> /// 获取Hash列表中的所有内容 /// </summary> /// <param name="hashId"></param> public Dictionary<string, string> getAllEntriesFromHash(string hashId) { return this.client.GetAllEntriesFromHash(hashId); } /// <summary> /// 判断Hash是否存在指定的键 /// </summary> /// <param name="hashId"></param> /// <param name="key"></param> /// <returns></returns> public bool hashContainsEntry(string hashId, string key) { return this.client.HashContainsEntry(hashId, key); } /// <summary> /// 设置多个值到Hash /// </summary> /// <param name="hashId"></param> /// <param name="keyValuePairs"></param> public void setRangeInHash(string hashId, Dictionary<string, string> keyValuePairs) { this.client.SetRangeInHash(hashId, keyValuePairs); } /// <summary> /// 获取Hash列表的长度 /// </summary> /// <param name="hashId"></param> /// <returns></returns> public long getHashCount(string hashId) { return this.client.GetHashCount(hashId); } /// <summary> /// 删除某一个值 /// </summary> /// <param name="hashId"></param> /// <param name="key"></param> /// <returns></returns> public bool removeEntryFromHash(string hashId, string key) { return this.client.RemoveEntryFromHash(hashId, key); } #endregion #region Set /// <summary> /// 从Set中获取随机值 /// </summary> /// <param name="setId"></param> /// <returns></returns> public string getRandomItemFromSet(string setId) { return this.client.GetRandomItemFromSet(setId); } /// <summary> /// 获取所有的值 /// </summary> /// <param name="setId"></param> /// <returns></returns> public HashSet<string> getAllItemsFromSet(string setId) { return this.client.GetAllItemsFromSet(setId); } /// <summary> /// 获取set的长度 /// </summary> /// <param name="setId"></param> /// <returns></returns> public long getSetCount(string setId) { return this.client.GetSetCount(setId); } /// <summary> /// 删除某一项 /// </summary> /// <param name="setId"></param> /// <param name="item"></param> public void removeItemFromSet(string setId, string item) { this.client.RemoveItemFromSet(setId, item); } /// <summary> /// 新增内容 /// </summary> /// <param name="setId"></param> /// <param name="item"></param> public void addItemToSet(string setId, string item) { this.client.AddItemToSet(setId, item); } /// <summary> /// 增加列表到Set /// </summary> /// <param name="setId"></param> /// <param name="items"></param> public void addRangeToSet(string setId, List<string> items) { this.client.AddRangeToSet(setId, items); } #endregion #region zset /// <summary> /// 添加元素到排序集合 /// </summary> /// <param name="setId"></param> /// <param name="value"></param> /// <returns></returns> public bool addItemToSortedSet(string setId, string value) { return this.client.AddItemToSortedSet(setId, value); } /// <summary> /// 添加元素到排序集合 /// </summary> /// <param name="setId"></param> /// <param name="value"></param> /// <param name="score"></param> /// <returns></returns> public bool addItemToSortedSet(string setId, string value, double score) { return this.client.AddItemToSortedSet(setId, value, score); } /// <summary> /// 增加列表到排序集合 /// </summary> /// <param name="setId"></param> /// <param name="values"></param> /// <param name="score"></param> /// <returns></returns> public bool addRangeToSortedSet(string setId, List<string> values, double score) { return this.client.AddRangeToSortedSet(setId, values, score); } /// <summary> /// 增加列表到排序集合 /// </summary> /// <param name="setId"></param> /// <param name="values"></param> /// <param name="score"></param> /// <returns></returns> public bool addRangeToSortedSet(string setId, List<string> values, long score) { return this.client.AddRangeToSortedSet(setId, values, score); } /// <summary> /// 获取所有的集合内容 /// </summary> /// <param name="setId"></param> /// <returns></returns> public List<string> getAllItemsFromSortedSet(string setId) { return this.client.GetAllItemsFromSortedSet(setId); } /// <summary> /// 倒序获取所有的内容 /// </summary> /// <param name="setId"></param> /// <returns></returns> public List<string> getAllItemsFromSortedSetDesc(string setId) { return this.client.GetAllItemsFromSortedSetDesc(setId); } /// <summary> /// 带分数一起取出 /// </summary> /// <param name="setId"></param> /// <returns></returns> public IDictionary<string, double> getAllWithScoresFromSortedSet(string setId) { return this.client.GetAllWithScoresFromSortedSet(setId); } /// <summary> /// 获取对应值的位置 /// </summary> /// <param name="setId"></param> /// <param name="value"></param> /// <returns></returns> public long getItemIndexInSortedSet(string setId, string value) { return this.client.GetItemIndexInSortedSet(setId, value); } /// <summary> /// 倒序的位置 /// </summary> /// <param name="setId"></param> /// <param name="value"></param> /// <returns></returns> public long getItemIndexInSortedSetDesc(string setId, string value) { return this.client.GetItemIndexInSortedSetDesc(setId, value); } /// <summary> /// 获取对应元素的分数 /// </summary> /// <param name="setId"></param> /// <param name="value"></param> /// <returns></returns> public double getItemScoreInSortedSet(string setId, string value) { return this.client.GetItemScoreInSortedSet(setId, value); } /// <summary> /// /// </summary> /// <param name="setId"></param> /// <param name="fromRank"></param> /// <param name="toRank"></param> /// <returns></returns> public List<string> getRangeFromSortedSet(string setId, int fromRank, int toRank) { return this.client.GetRangeFromSortedSet(setId, fromRank, toRank); } public IDictionary<string, double> getRangeWithScoresFromSortedSet(string setId, int fromRank, int toRank) { return this.client.GetRangeWithScoresFromSortedSet(setId, fromRank, toRank); } #endregion #region 其它 public void Transcation() { using (IRedisTransaction irt = this.client.CreateTransaction()) { try { irt.QueueCommand(r => r.Set("key", 20)); irt.QueueCommand(r => r.Increment("key", 1)); irt.Commit(); // 提交事务 } catch (Exception ex) { irt.Rollback(); throw ex; } } } /// <summary> /// 清除全部数据 /// </summary> public virtual void FlushAll() { client.FlushAll(); } /// <summary> /// 保存数据DB文件到硬盘 /// </summary> public void Save() { client.Save();//阻塞式save } /// <summary> /// 异步保存数据DB文件到硬盘 /// </summary> public void SaveAsync() { client.SaveAsync();//异步save } #endregion public void Dispose() { if (this.client != null) { this.client.Dispose(); } } }