刚刚部署docker里的redis-stack的时候发现启动不起来,查来查去发现是环境变量的问题,以前我的环境变量是这么写的
`REDIS_ARGS=”–requirepass redis密码”`
但这样就会导致标题上的错误,需要把引号去掉
`REDIS_ARGS=–requirepass redis密码`
刚刚部署docker里的redis-stack的时候发现启动不起来,查来查去发现是环境变量的问题,以前我的环境变量是这么写的
`REDIS_ARGS=”–requirepass redis密码”`
但这样就会导致标题上的错误,需要把引号去掉
`REDIS_ARGS=–requirepass redis密码`
mysql中update的基础用法是update 表 set 列1=?,列2=?,... where 筛选条件
,这样的语句一次只可以对符合条件的所有行更新相同的数据,但update语句还可以join其它的表,从别的表读取数据更新到对应的行上,这样就可以实现对不同的行更新不同的数据,如下:
update 表名 as t1 inner join 表2 as t2 #也可以left join 或 right join 或 join,这里的join和select里面那个join用法是一样的 on t1.id列名=t2.id列名 set t1.列1 = t2.列1, t1.列2 = t2.列2
虽然上面的方法能实现标题的要求,但总不能先把数据插入一个表再这样update吧,于是我想了一会儿,想到如果要提交多组数据肯定要把数据结构化,如果要提交结构化数据那肯定是要用json,mysql 的json函数里有一个`JSON_TABLE`函数可以用来把一个json转换成一个表类型,那么这个方法就好实现了,只要把上面的表2替换成用JSON_TABLE生成的表,就可以通过直接向mysql提供一个json来对不同的行更新不同的数据了,如下:
update 表名 as t1 inner join JSON_TABLE( ?, '$[*]' COLUMNS ( #把json作为一个数组遍历,提取每个子数组作为数据源 id列名 BIGINT PATH '$[0]', #提取子数组第一个元素,取名为"id列名",类型是BIGINT,建议取名为目标表中的id列名,这样方便用using 列1 INT PATH '$[1]', #提取子数组第二个元素,取名为"列1",类型是INT 列2 VARCHAR PATH '$[2]' #提取子数组第三个元素,取名为"列2",类型是VARCHAR ) ) as t2 using(id列名) #这个using是前一个例子中on语法的一种简写,用法参考官方文档 set t1.列1 = t2.列1, t1.列2 = t2.列2;
在 ? 的位置填入一个json字符串或者prepare这个语句后提交一个json字符串,就可以啦。json字符串示例如下:
[ [1,20,"张三"], [2,24,"李四"], [3,18,"王五"], [4,23,"赵六"], [5,55,"小二"], [6,60,"poi"] ]
这样每个子数组中的第一个项目被提取为”id列名”,第二个为”列1″,第三个为”列2″(都是在上面的sql里的JSON_TABLE里取的名字),对应的值在set语句里被赋值到对应的行上,功能就完成啦。
今天在搭建MinGPT-4环境的时候出现了这个错误,查了一下,好像是配置里的名字大小写错了,尝试把`llama-13b-hf\tokenizer_config.json`里面的`LLaMATokenizer`替换成`LlamaTokenizer`即可解决,之后的版本应该会修复这个错误。
我一直到刚刚才发现我的blog已经好久没给我发送自动备份了,然后后台里找了找原因,发现在“站点健康”页面显示“您的站点不能完成环回请求”,然后下面还有别的提示表示因为这个原因,定时任务无法启动。
于是我开始找为什么它会无法发送请求给自己,进到容器里用curl -v请求本站,发现域名解析到了容器的IP地址,但容器上开放的端口并不是443,所以会出现“Connection refused”错误。
然后再继续找为什么域名会被解析到容器ip,猜想肯定和docker的某些策略有关,搜了一下,原来是因为我给它使用了自定义网络,和默认网络不同的是自定义网络里容器名会被用于同网络中域名的dns解析,我的容器名就是luojia.me,结果就是wordpress请求自己的地址时被解析到了容器ip,导致请求失败。
解决方式就是把容器名换掉,比如加个前缀之类的就解决了。
在`package.json`中直接修改了依赖版本号后执行`npm i`可能会出现各种报错,比如`Error: Cannot find module xxx`之类的。
这时候需要删除`package-lock.json`并删除`node_modules`目录后重新执行`npm i`应该就可以恢复正常
这一个奇怪的bug困扰了我2天半,浪费了我很多时间来反复修改调试找问题,最后虽然找到了问题点,但是依然不知道是怎么发生的。
和网上很多其它能找到的页面不刷新的问题不同,他们要么是忘了写`<router-view>`,要么就是靠给`<router-view>`加key来解决缓存问题。而我这里的症状是页面加载后直接显示了最后一个路由的内容,不管点哪个链接都会显示最后添加的路由组件的内容。
最后我在控制台打出了所有组件的渲染函数和data函数才发现,并不是vue在渲染时选错了渲染对象,而是所有组件的渲染函数和data函数都直接指向了最后一个路由的函数,但我并没有代码去动态修改这些组件的函数,于是我在某个组件的data函数里填了一点数据再测试,问题就解决了。
由于是测试组件,原本data返回的对象是空的,像这样:
export default { data() { return { }; }, }
填完数据之后变成这样:
export default { data() { return { poi:'poipoi', }; }, }
然后这一个组件里面就不会自动变成最后一个路由组件的render函数和data函数了,但如果两个组件里面data返回的对象填写的内容也一样,那么前一个组件里面的这两个函数依然会指向后一个的,这在代码逻辑上怎么都讲不通,只能说应该是在某个优化环节出问题了,把字面一样的函数直接简化成了同一个,然后就产生了这种所有路由组件全部渲染出最后一个组件的内容的情况。
这耳机从买来到现在从来没清洁过,其实用得也不算多,但耳罩上还是越来越油了,光是擦实在不能擦干净,所以我决定还是要拆下来洗洗。
网上查了一下,实际上很好拆,只要拿个比较扁平细长的硬物插进耳罩卡扣附近边缘的缝隙里往上撬就行了,具体哪里有卡扣可以参考下面两张图。
当然如果你怎么撬都出不来也千万不能大力出奇迹,不然耳套皮必坏。正确的感觉应该是往上撬时能明显感觉到有东西被撬起来了,如果没有这种感觉就不要硬掰了,换个位置重试吧。
清洗的时候我就用水冲了之后拿洗手液搓了搓,冲干净然后压一压把水挤出来,最后放机箱上烤了半天就好了。安装回去的时候只要注意好左右耳(上面的定位柱位置不一样)然后按回去就行了。
我这WF-1000XM4买来在质保期内已经换过左耳单元,所以左耳电池寿命还没什么问题,但右耳的电池已经连半小时都撑不到了,太离谱了。
因为刚好过了质保两个月,问了客服,也是说质保已过,而且他们不会换电池,要解决就得直接买整个耳机单元好像大概500元左右,那谁高兴去搞,万一换完了过一年又这样呢,于是我勉强就这么先用着。
上星期我本想逛逛看看有没有什么替代品,偶然看到有些耳机维修业务,然后顺着搜了一下,果然有专门给这耳机换电池的,但是一看价格劝退了。然后我搜了一下是否有教程,看了看好像也不难,于是按照搜到的电池型号买了个电池回来自己换。
首先拿掉耳塞,用热风枪开100度对着耳机一直吹,吹到整个耳机都发烫之后就可以开始用美工刀撬了,有条件的话最好用风枪一直对着吹,避免冷却增加难度。
撬的时候用美工刀顺着耳机的接缝插进去,然后上下掰动,力道适当几乎不会留下痕迹。慢慢多来几下,缝就会越来越大,缝到足够指甲塞进去的程度之后直接用手掰就行了,但是一定要小心,因为两半里面是有排线连在一起的,掰开后就是如下图:
此博文由一个话题引出,原话题是通过滑条控制页面上显示3D模型的某个部分,于是我就来尝试了一下。
由于Three.js我也已经2年没碰了,而且在项目里只用过一次,所以并不是很清楚它是否能通过本身的功能达到这个效果,甚至一开始我已经在想手搓点坐标来达到目标了。
但手搓点坐标实在太麻烦了一点,我就回到blender想看看通常用于控制形变的形态键是否可以导出来使用,然后发现确实可以,这样就方便了,只要控制形态键的数值就可以对模型的形态进行定量控制,以下是操作过程: 继续阅读[WebGL]使用javascript控制模型形变
今天博客莫名其妙开始报数据库连接错误,重启了之后也还是一样,一看mysql日志,看来又是老问题,硬盘空间被占满了。
每次都要等到出问题了再来删日志实在太麻烦,查了一下nginx也没有自带缩减日志的功能,查到有用logrotate来自动分割和压缩日志的,不过我只是想简单地把日志文件缩小,能看到最近的日志就够了,所以还是自己写个脚本。
代码很简单,用tail命令把日志文件的最后20000行裁出来存到新文件,然后用新的日志文件替换旧文件,把这个脚本放到cron的daily目录中每日执行一次即可
cd nginx日志目录 tail -n 20000 -q access.log > access.log.new mv access.log.new access.log tail -n 20000 -q error.log > error.log.new mv error.log.new error.log
这段脚本把access.log和error.log都裁剪了。
要注意的是这种办法虽然简单,但是如果在tail执行的时候nginx又向日志文件写入了新的内容,这部分内容可能会被丢弃,所以只能用于我这种简单场景,对于日志有严格保存需求的场景不能使用该方法,应该用logrotate。
reids本身是一个基于键值对数据存储的内存数据库,也就是只能通过数据的key来获取数据项目,那么它自然也就没有任何数据搜索方面的功能,只能依靠一定规则生成的key来获取数据。
虽然它的本体是这样,但redis也提供了几个模块为其添加了一部分搜索功能的支持,并将这些模块整合为了redis-stack,官网介绍:https://redis.io/docs/stack/,我暂时还没测试它是否可以直接替代原本的redis实例,但就命令形式上来看,应该是兼容的。
本文是对于redis-stack官网上提供的node.js示例记录的笔记。
redis-stack的安装我就不介绍了,直接从官网下载就好,或者使用docker之类的,本文只记录如何使用。
要在node.js中使用redis-stack的相关特性,我们需要`redis-om`模块,使用`npm i redis-om`安装进需要它的项目,关于该模块更详细的API介绍可以去其npm包页面上或者github仓库查看:https://github.com/redis/redis-om-node,不过要注意的是官方的示例中有些地方是错的,我会在下面对应的部分说明。 继续阅读[node.js]在redis上使用数据搜索
我的Mix2s不知道从什么时候开始出现了打电话时屏幕不灭,或者灭掉了之后又没法亮屏的问题,甚至还有打电话时有一定概率对方会完全听不见自己声音的情况,
原本我一直以为是刷的LineageOS和这硬件不太兼容,于是想着可能某次更新之后就解决了。
但我最近升了一个大版本之后发现这个问题依然存在,于是我网上查了几天,发现很多人都有这样的情况,而且和系统无关,全都有这种现象。
再仔细一查,发现似乎是因为距离传感器在长时间使用过程中被细小灰尘堵住了,导致它的超声波距离传感器灵敏度变差。
Mix2s的超声波距离传感器位于听筒两边,是从听筒的孔两边延伸出去的两条非常细的缝,长度大约各1厘米,用眼睛不太容易看出来,需要灯光位于一个特殊角度时你才可以发现听筒两边有一部分的缝比旁边要大一点点(如下图),用美工刀片是可以卡进去一点的。
修复方案那就是先用美工刀插进超声波缝,然后把里面固化的灰尘划出来,注意小心点别把听筒捅坏了,能划的灰都弄出来之后用能插得进缝的软毛刷狂捅一顿,再左右刷刷,尽量把能看到的灰都刷掉。
这样处理完之后距离传感器就可以恢复正常的感应距离了,也不那么容易出现卡在一个状态不变化的情况(但由于设计缺陷,某些情况下还是会有距离状态不变的问题,这个无法修复)
之前有一篇文章写的是在mysql中使用json字段时为其中的数组创建索引,它有个问题就是当该字段本身存放的就是一个数组时(不放在对象下的属性中),这样创建的索引不生效,原因不明。因此要使索引生效需要把数组放在对象下的一个属性里。
现在我发现,如果想要在mysql中存放一个可以索引的json数组,其实根本不需要使用json字段,即使是普通的字符串字段存放的json数组也可以用同样的方法进行索引。
比如现在有一个字段`tags`,类型为`mediumtext`,在其中一行存放了以下字符串:
[1,2,3,4,5,6,7,8,9,10]
然后将其解析为json来创建多值索引:
ALTER TABLE 表 ADD INDEX tag_idx((cast(JSON_EXTRACT(tags, '$') as unsigned array)))
接着在查询数据时也把该字段解析为json进行使用:
SELECT * FROM 表 WHERE JSON_OVERLAPS('[1,2]',JSON_EXTRACT(tags, '$'))
在这样的查询中,mysql就会使用到这个json数组的索引,因此如果一个数据仅仅是为了作为数组使用的话就没必要套个对象放进json字段了,使用普通字符串字段即可。
刚刚发现程序里有一个语句,是一个unique主键 member of(返回json数组的子查询)
,但它就是不走主键索引,接着我把子查询换成了一个手写的json串,像这样
SELECT tag_id FROM tags FORCE INDEX ( tag_id_unique ) WHERE tag_id member of (JSON_EXTRACT( '[1,2,3]', '$' ))
发现即使是指定了索引也还是不走索引,可能member of就是这样的机制? 目前原因还不清楚,于是我先用了另一个办法。
碰到一个需要给图表上数据打颜色的场景,我希望对于同一个名字的数据每次出来的颜色都是一样的,于是想了半分钟,搞出了这么个方案
function strToRGB(name){ let sum=0; for(let s of name)sum+=s.codePointAt(0); return [sum%128,sum%126,sum%124]; }
原理是把每一个字符的unicode值累加起来,然后对这个和分别取3个余数。
除数选1到256都可以,选多少取决于希望结果出现在哪个范围,我这里为了让结果颜色偏暗,所以选了128左右的除数。
首先容我说一句,搞出自动唤醒电脑更新系统这个策略的人是烧饼,搞出更新后无视用户任务自动重启电脑的人也是烧饼,说不定还是同一个人。
从Win10开始就有不少人遇到了这个问题,最后发现是系统更新半夜唤醒了电脑,关闭方法是在“任务计划程序”里找到”\Microsoft\Windows\UpdateOrchestrator\Schedule Wake To Work”这一项,把它禁用,如果提示权限不够无法操作,可以搜索一下如何禁用这个任务计划。
这篇文章我要说的是另一个问题,自从升级到Win11之后,之前在10里面已经改过的设置又被改回来了,又开始每天晚上自动开机跑更新,而且即使再改,它依然会被恢复到默认状态,晚上还是会自动开机,真实烧饼行为。于是只能换个办法来解决这个问题,我找到的一个办法是,既然任务计划唤醒电脑靠的是唤醒定时器,那么只要把唤醒定时器整个禁用掉应该就好了。
关闭方法是在当前的电源计划设置里找到“睡眠”→”允许使用唤醒定时器“,把启用改成禁用即可。现在几个晚上下来都没有再出现自动启动的情况了。